diff options
| -rw-r--r-- | opendc-core/build.gradle | 8 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Bootstrap.kt | 64 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Context.kt | 184 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Entity.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt) | 12 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Process.kt | 27 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Time.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/Time.kt) | 2 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/Kernel.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulation.kt) | 57 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/KernelFactory.kt | 42 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/platform/Experiment.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/platform/Experiment.kt) | 18 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Context.kt | 120 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Interrupt.kt | 32 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Kernel.kt | 50 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Process.kt | 51 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Envelope.kt | 50 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Readable.kt | 75 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Receipt.kt | 53 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Writable.kt | 54 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/sampler/Sampler.kt | 40 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/Clock.kt | 79 | ||||
| -rw-r--r-- | opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/TickClock.kt | 60 | ||||
| -rw-r--r-- | opendc-kernel-omega/build.gradle (renamed from opendc-omega/build.gradle) | 7 | ||||
| -rw-r--r-- | opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/MessageContainer.kt (renamed from opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/MessageContainer.kt) | 34 | ||||
| -rw-r--r-- | opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaKernel.kt | 315 | ||||
| -rw-r--r-- | opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaKernelFactory.kt (renamed from opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaKernel.kt) | 29 | ||||
| -rw-r--r-- | opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/Resume.kt (renamed from opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/Resume.kt) | 5 | ||||
| -rw-r--r-- | opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/Timeout.kt (renamed from opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/Timeout.kt) | 4 | ||||
| -rw-r--r-- | opendc-kernel-omega/src/test/kotlin/com/atlarge/opendc/omega/SmokeTest.kt (renamed from opendc-omega/src/test/kotlin/nl/atlarge/opendc/SmokeTest.kt) | 95 | ||||
| -rw-r--r-- | opendc-model-odc/core/build.gradle | 87 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/OdcModel.kt | 10 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/FifoScheduler.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/FifoScheduler.kt) | 12 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/Scheduler.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/Scheduler.kt) | 12 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/SrtfScheduler.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/SrtfScheduler.kt) | 11 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Job.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Job.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Task.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Task.kt) | 6 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/TaskState.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/TaskState.kt) | 4 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Trace.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Trace.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/User.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/User.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Datacenter.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt) | 32 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Rack.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Rack.kt) | 7 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Room.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt) | 7 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Cpu.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Gpu.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Machine.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt) | 34 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/ProcessingUnit.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt) | 7 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/network/NetworkUnit.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/network/NetworkUnit.kt) | 7 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/power/PowerUnit.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt) | 7 | ||||
| -rw-r--r-- | opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/storage/StorageUnit.kt (renamed from opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/storage/StorageUnit.kt) | 7 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/build.gradle (renamed from opendc-integration-jpa/core/build.gradle) | 9 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaBootstrap.kt | 44 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaModel.kt | 14 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/Jpa.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/Jpa.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/ParallelizableConverter.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/ParallelizableConverter.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/SchedulerConverter.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/SchedulerConverter.kt) | 8 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Cpu.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Cpu.kt) | 4 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Datacenter.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Datacenter.kt) | 8 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Experiment.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Experiment.kt) | 8 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/ExperimentState.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/ExperimentState.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Gpu.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Gpu.kt) | 4 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Job.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Job.kt) | 7 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Machine.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Machine.kt) | 4 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/MachineState.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/MachineState.kt) | 4 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Path.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Path.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Rack.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Rack.kt) | 4 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Room.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Room.kt) | 4 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomObject.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomObject.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomType.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomType.kt) | 2 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Section.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Section.kt) | 4 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Task.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt) | 8 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/TaskState.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/TaskState.kt) | 4 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Trace.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Trace.kt) | 6 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperiment.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt) | 85 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperimentManager.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt) | 12 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/topology/JpaTopologyFactory.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/topology/JpaTopologyFactory.kt) | 12 | ||||
| -rw-r--r-- | opendc-model-odc/jpa/src/main/resources/jpa/schema.xml (renamed from opendc-integration-jpa/core/src/main/resources/jpa/schema.xml) | 14 | ||||
| -rw-r--r-- | opendc-model-odc/setup/Dockerfile (renamed from opendc-integration-jpa/mysql/Dockerfile) | 4 | ||||
| -rw-r--r-- | opendc-model-odc/setup/build.gradle (renamed from opendc-integration-jpa/mysql/build.gradle) | 53 | ||||
| -rw-r--r-- | opendc-model-odc/setup/src/main/kotlin/platform/JpaPlatformRunner.kt (renamed from opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt) | 7 | ||||
| -rw-r--r-- | opendc-model-odc/setup/src/main/resources/META-INF/persistence.xml (renamed from opendc-integration-jpa/mysql/src/main/resources/META-INF/persistence.xml) | 0 | ||||
| -rw-r--r-- | opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaSimulation.kt | 398 | ||||
| -rw-r--r-- | opendc-stdlib/build.gradle | 6 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt) | 38 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt | 23 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Component.kt) | 2 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt) | 8 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/MutableTopology.kt) | 13 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Topology.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Topology.kt) | 6 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyBuilder.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt) | 2 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyContext.kt) | 10 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyFactory.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyFactory.kt) | 2 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyListener.kt) | 8 | ||||
| -rw-r--r-- | opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Traversable.kt) | 2 | ||||
| -rw-r--r-- | settings.gradle | 7 |
92 files changed, 1226 insertions, 1469 deletions
diff --git a/opendc-core/build.gradle b/opendc-core/build.gradle index 92cdb2c4..f1eac0da 100644 --- a/opendc-core/build.gradle +++ b/opendc-core/build.gradle @@ -24,7 +24,7 @@ /* Build configuration */ buildscript { - ext.kotlin_version = '1.1.4-3' + ext.kotlin_version = '1.2.10' ext.dokka_version = '0.9.15' repositories { @@ -68,8 +68,8 @@ dokka { } /* Project configuration */ -group 'nl.atlarge.opendc' -version '1.0' +group 'com.atlarge.opendc' +version '1.1' repositories { jcenter() @@ -78,7 +78,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.18" + compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.21" testCompile "org.junit.jupiter:junit-jupiter-api:5.0.0-RC3" testRuntime "org.junit.jupiter:junit-jupiter-engine:5.0.0-RC3" diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Bootstrap.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Bootstrap.kt new file mode 100644 index 00000000..199e1701 --- /dev/null +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Bootstrap.kt @@ -0,0 +1,64 @@ +package com.atlarge.opendc.simulator + +/** + * A bootstrapping interface for a conceptual model that is a logical representation of some system of entities, + * relationships and processes, as a basis for simulations. + * + * @param M The shape of the model that is bootstrapped. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Bootstrap<M> { + /** + * Bootstrap a model `M` for a kernel in the given context. + * + * @param context The context to bootstrap to model in. + * @return The initialised model for the simulation. + */ + fun bootstrap(context: Context<M>): M + + /** + * A context for the bootstrap of some model type `M` that allows the model to register the entities of the model to + * the simulation kernel. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ + interface Context<out M> { + /** + * Register the given entity to the simulation kernel. + * + * @param entity The entity to register. + * @return `true` if the entity had not yet been registered, `false` otherwise. + */ + fun register(entity: Entity<*, M>): Boolean + + /** + * Deregister the given entity from the simulation kernel. + * + * @param entity The entity to deregister. + * @return `true` if the entity had not yet been unregistered, `false` otherwise. + */ + fun deregister(entity: Entity<*, M>): Boolean + + /** + * Schedule a message for processing by a [Context]. + * + * @param message The message to schedule. + * @param destination The destination of the message. + * @param sender The sender of the message. + * @param delay The amount of time to wait before processing the message. + */ + fun schedule(message: Any, destination: Entity<*, *>, sender: Entity<*, *>? = null, delay: Duration = 0) + } + + companion object { + /** + * Create a [Bootstrap] procedure using the given block to produce a bootstrap for a model of type `M`. + * + * @param block The block to produce the bootstrap. + * @return The bootstrap procedure that has been built. + */ + fun <M> create(block: (Context<M>) -> M): Bootstrap<M> = object : Bootstrap<M> { + override fun bootstrap(context: Context<M>) = block(context) + } + } +} diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Context.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Context.kt new file mode 100644 index 00000000..c4e906dd --- /dev/null +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Context.kt @@ -0,0 +1,184 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.simulator + +import java.util.Queue + +/** + * This interface provides a context for simulation of [Entity] instances, by defining the environment in which the + * simulation is run and provides means of communicating with other entities in the environment and control its own + * behaviour. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Context<S, out M> { + /** + * The model of simulation in which the entity exists. + */ + val model: M + + /** + * The current point in simulation time. + */ + val time: Instant + + /** + * The duration between the current point in simulation time and the last point in simulation time where the + * [Entity] has done some work. This means the `run()` co-routine has been resumed. + */ + val delta: Duration + + /** + * The observable state of the entity bound to this scope. + */ + var state: S + + /** + * The observable state of an [Entity] in simulation, which is provided by the simulation context. + */ + val <E : Entity<S, *>, S> E.state: S + + /** + * Interrupt an [Entity] process in simulation. + * + * If an [Entity] process has been suspended, the suspending call will throw an [Interrupt] object as a result of + * this call. + * Make sure the [Entity] process actually has error handling in place, so it won't take down the whole [Entity] + * process as result of the interrupt. + */ + suspend fun Entity<*, *>.interrupt() + + /** + * Suspend the [Context] of the [Entity] in simulation for the given duration of simulation time before resuming + * execution and drop all messages that are received during this period. + * + * A call to this method will not make the [Context] sleep for the actual duration of time, but instead suspend + * the process until the no more messages at an earlier point in time have to be processed. + * + * @param duration The duration of simulation time to hold before resuming execution. + */ + suspend fun hold(duration: Duration) + + /** + * Suspend the [Context] of the [Entity] in simulation for the given duration of simulation time before resuming + * execution and push all messages that are received during this period to the given queue. + * + * A call to this method will not make the [Context] sleep for the actual duration of time, but instead suspend + * the process until the no more messages at an earlier point in time have to be processed. + * + * @param duration The duration of simulation time to wait before resuming execution. + * @param queue The mutable queue to push the messages to. + */ + suspend fun hold(duration: Duration, queue: Queue<Any>) + + /** + * Retrieve and remove a single message from the instance's mailbox, suspending the function if the mailbox is + * empty. The execution is resumed after the head of the mailbox is removed after which the message [Envelope] is + * transformed through `transform` to return the transformed result. + * + * @param transform The block to transform the message with in an envelope context, providing access to the sender + * of the message. + * @return The transformed message. + */ + suspend fun <T> receive(transform: suspend Envelope<*>.(Any) -> T): T + + /** + * Retrieve and remove a single message from the instance's mailbox, suspending the function if the mailbox is + * empty. The execution is either resumed after the head of the mailbox is removed after which the message + * [Envelope] is transformed through `transform` to return the transformed result or the timeout has been reached. + * + * @param timeout The duration to wait before resuming execution. + * @param transform The block to transform the message with in an envelope context, providing access to the sender + * of the message. + * @return The processed message or `null` if the timeout was reached. + */ + suspend fun <T> receive(timeout: Duration, transform: suspend Envelope<*>.(Any) -> T): T? + + /** + * Retrieve and remove a single message from the instance's mailbox, suspending the function if the mailbox is + * empty. The execution is resumed after the head of the mailbox is removed and returned. + * + * @return The received message. + */ + suspend fun receive(): Any = receive { it } + + /** + * Retrieve and remove a single message from the instance's mailbox, suspending the function if the mailbox is + * empty. The execution is either resumed after the head of the mailbox is removed and returned or when the timeout + * has been reached. + * + * @return The received message or `null` if the timeout was reached. + */ + suspend fun receive(timeout: Duration): Any? = receive(timeout) { it } + + /** + * Send the given message to the specified entity, without providing any guarantees about the actual delivery of + * the message. + * + * @param msg The message to send. + * @param delay The amount of time to wait before the message should be received by the entity. + */ + suspend fun Entity<*, *>.send(msg: Any, delay: Duration = 0) + + /** + * Send the given message to the specified entity, without providing any guarantees about the actual delivery of + * the message. + * + * @param msg The message to send. + * @param sender The sender of the message. + * @param delay The amount of time to wait before the message should be received by the entity. + */ + suspend fun Entity<*, *>.send(msg: Any, sender: Entity<*, *>, delay: Duration = 0) +} + +/** + * The message envelope that is sent to an [Entity], also containing the metadata of the message. + * + * @param T The shape of the message inside the envelope. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Envelope<out T: Any> { + /** + * The message in this envelope. + */ + val message: T + + /** + * The sender of the message. + */ + val sender: Entity<*, *>? + + /** + * The destination of the message. + */ + val destination: Entity<*, *> +} + +/** + * An [Interrupt] message is sent to a [Entity] process in order to interrupt its suspended state. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +object Interrupt: Throwable("The entity process has been interrupted by another entity") diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Entity.kt index 66a31d77..800f2f1d 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Entity.kt @@ -22,21 +22,21 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.simulator /** - * An entity within a cloud network, represented as a node within a topology. + * An entity in some model `M`. * - * <p>A [Entity] contains immutable properties given by the topology configuration at the start of a simulation and - * remain unchanged during simulation. + * <p>A [Entity] directly contains its immutable properties that remain unchanged during simulation. * - * <p>In addition, other entities in a simulation have direct, immutable access to the observable state of this entity. + * <p>In addition, other entities in simulation have direct, immutable access to the observable state of this entity. * * @param S The shape of the observable state of this entity, which is directly accessible by other components within * a simulation. + * @param M The shape of the model in which the entity exists. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Entity<out S> : Component { +interface Entity<out S, in M> { /** * The initial state of the entity. */ diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Process.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Process.kt new file mode 100644 index 00000000..30280657 --- /dev/null +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Process.kt @@ -0,0 +1,27 @@ +package com.atlarge.opendc.simulator + +/** + * A process is dynamic entity within a simulation, that interacts with the model environment by the interchange of + * messages. + * + * @param S The shape of the observable state of the process. + * @param M The shape of the model in which the process exists. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Process<S, in M>: Entity<S, M> { + /** + * This method is invoked to start the simulation a process. + * + * This method is assumed to be running during a simulation, but should hand back control to the simulator at + * some point by suspending the process. This allows other processes to do work at the current point in time of the + * simulation. + * Suspending the process can be achieved by calling suspending method in the context: + * - [Context.hold] - Hold for `n` units of time before resuming execution. + * - [Context.receive] - Wait for a message to be received in the mailbox of the [Entity] before resuming + * execution. + * + * If this method exits early, before the simulation has finished, the entity is assumed to be shutdown and its + * simulation will not run any further. + */ + suspend fun Context<S, M>.run() +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/Time.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Time.kt index af9d547b..64e3cb80 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/Time.kt +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Time.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.kernel.time +package com.atlarge.opendc.simulator /** * An instantaneous point on the time-line, used to record event time-stamps in a simulation. diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulation.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/Kernel.kt index d07c3ba0..3eee0f67 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulation.kt +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/Kernel.kt @@ -22,49 +22,39 @@ * SOFTWARE. */ -package nl.atlarge.opendc.kernel +package com.atlarge.opendc.simulator.kernel -import nl.atlarge.opendc.kernel.messaging.Receipt -import nl.atlarge.opendc.kernel.time.Clock -import nl.atlarge.opendc.kernel.time.Duration -import nl.atlarge.opendc.kernel.time.Instant -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.Topology -import java.lang.Process +import com.atlarge.opendc.simulator.Bootstrap +import com.atlarge.opendc.simulator.Instant +import com.atlarge.opendc.simulator.Entity /** - * A message based discrete event simulation facilitated by a simulation [Kernel]. + * A message based discrete event simulation kernel. * - * In order for the simulation to run, the simulation kernel needs to bootstrapped by an set of messages to be processed - * initially by entities in the topology of the simulation. Otherwise, the simulation will immediately exit. - * Bootstrapping can be achieved by scheduling messages before running the simulation via [Simulation.schedule]: + * The kernel is created by bootstrapping some model `M` (see [Bootstrap]) to simulate and controls the simulation by + * allowing the user to step over cycles in the simulation and inspect the internal state using [Entity.state]. * - * `val simulation = kernel.create(topology).apply { - * schedule(Boot, entity) - * }` + * A kernel should provide additionally a [KernelFactory] to create new kernel instances given a certain model + * [Bootstrap]. * + * @param M The shape of the model over which the simulation runs. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Simulation { +interface Kernel<out M> { /** - * The [Kernel] that facilitates the simulation. + * The model in which the simulation runs. */ - val kernel: Kernel + val model: M /** - * The [Topology] over which the simulation is run. + * The simulation time. */ - val topology: Topology - - /** - * The [Clock] instance that keeps track of simulation time. - */ - val clock: Clock + var time: Instant /** * The observable state of an [Entity] in simulation, which is provided by the simulation context. */ - val <E : Entity<S>, S> E.state: S + val <E : Entity<S, *>, S> E.state: S /** * Step through one cycle in the simulation. This method will process all events in a single tick, update the @@ -73,28 +63,17 @@ interface Simulation { fun step() /** - * Run a simulation over the specified [Topology]. + * Run a simulation over the specified model. * This method will step through multiple cycles in the simulation until no more message exist in the queue. */ fun run() /** - * Run a simulation over the specified [Topology], stepping through cycles until the specified clock tick has + * Run a simulation over the specified model, stepping through cycles until the specified clock tick has * occurred. The control is then handed back to the user. * * @param until The point in simulation time at which the simulation should be paused and the control is handed * back to the user. */ fun run(until: Instant) - - /** - * Schedule a message for processing by a [Process]. - * - * @param message The message to schedule. - * @param destination The destination of the message. - * @param sender The sender of the message. - * @param delay The amount of time to wait before processing the message. - * @return A [Receipt] of the message that has been scheduled. - */ - fun schedule(message: Any, destination: Entity<*>, sender: Entity<*>? = null, delay: Duration = 0): Receipt } diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/KernelFactory.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/KernelFactory.kt new file mode 100644 index 00000000..93667eb8 --- /dev/null +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/KernelFactory.kt @@ -0,0 +1,42 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.simulator.kernel + +import com.atlarge.opendc.simulator.Bootstrap + +/** + * A factory for bootstrapping simulation [Kernel] instances. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface KernelFactory { + /** + * Create a simulation over the given model facilitated by this simulation kernel. + * + * @param bootstrap The bootstrap procedure to bootstrap the simulation with. + * @return A [Kernel] instance to control the simulation. + */ + fun <M> create(bootstrap: Bootstrap<M>): Kernel<M> +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/platform/Experiment.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/platform/Experiment.kt index 6aed5364..88b606fd 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/platform/Experiment.kt +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/platform/Experiment.kt @@ -22,10 +22,10 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform +package com.atlarge.opendc.simulator.platform -import nl.atlarge.opendc.kernel.Kernel -import nl.atlarge.opendc.kernel.time.Duration +import com.atlarge.opendc.simulator.kernel.KernelFactory +import com.atlarge.opendc.simulator.Duration /** * A blueprint for a reproducible simulation in a pre-defined setting. @@ -34,19 +34,19 @@ import nl.atlarge.opendc.kernel.time.Duration */ interface Experiment<out T> { /** - * Run the experiment on the specified simulation [Kernel]. + * Run the experiment on the specified kernel implementation. * - * @param kernel The simulation kernel to run the experiment. + * @param factory The factory to create the simulation kernel with. * @return The result of the experiment. */ - fun run(kernel: Kernel): T + fun run(factory: KernelFactory): T /** - * Run the experiment on the specified simulation [Kernel]. + * Run the experiment on the specified kernel implementation. * - * @param kernel The simulation kernel to run the experiment. + * @param factory The factory to create the simulation kernel with. * @param timeout The maximum duration of the experiment before returning to the caller. * @return The result of the experiment or `null`. */ - fun run(kernel: Kernel, timeout: Duration): T? + fun run(factory: KernelFactory, timeout: Duration): T? } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Context.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Context.kt deleted file mode 100644 index 83a7c4fb..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Context.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel - -import nl.atlarge.opendc.kernel.messaging.Readable -import nl.atlarge.opendc.kernel.messaging.Writable -import nl.atlarge.opendc.kernel.time.Clock -import nl.atlarge.opendc.kernel.time.Duration -import nl.atlarge.opendc.kernel.time.Instant -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.MutableTopology -import nl.atlarge.opendc.topology.Topology -import nl.atlarge.opendc.topology.TopologyContext -import java.lang.Process -import java.util.* - -/** - * This interface provides a context for simulation [Process]es, which defines the environment in which the simulation - * is run and provides means of communicating with other entities in the environment and control its own behaviour. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Context<out E : Entity<*>> : Readable, Writable, TopologyContext { - /** - * The [Entity] in simulation by the [Process]. - */ - val entity: E - - /** - * The [Topology] over which the simulation is run. - */ - val topology: MutableTopology - - /** - * The current point in simulation time. - */ - val time: Instant - - /** - * The duration between the current point in simulation time and the last point in simulation time where the - * [Process] has executed some work. This means the `run()` co-routine has been resumed. - */ - val delta: Duration - - /** - * The observable state of an [Entity] in simulation, which is provided by the simulation context. - */ - val <E : Entity<S>, S> E.state: S - - /** - * Update the observable state of the entity being simulated. - * - * Instead of directly mutating the entity, we create a new instance of the entity to prevent other objects - * referencing the old entity having their data changed. - * - * @param next The next state of the entity. - */ - suspend fun <C : Context<E>, E : Entity<S>, S> C.update(next: S) - - /** - * Interrupt the [Process] of an [Entity] in simulation. - * - * If a [Process] has been suspended, the suspending call will throw an [Interrupt] object as a result of this call. - * Make sure the [Process] actually has error handling in place, so it won't take down the whole [Process]. - */ - suspend fun Entity<*>.interrupt() - - /** - * Suspend the [Process] of the [Entity] in simulation for the given duration of simulation time before resuming - * execution and drop all messages that are received during this period. - * - * A call to this method will not make the [Process] sleep for the actual duration of time, but instead suspend - * the process until the no more messages at an earlier point in time have to be processed. - * - * @param duration The duration of simulation time to wait before resuming execution. - */ - suspend fun wait(duration: Duration) - - /** - * Suspend the [Process] of the [Entity] in simulation for the given duration of simulation time before resuming - * execution and push all messages that are received during this period to the given queue. - * - * A call to this method will not make the [Process] sleep for the actual duration of time, but instead suspend - * the process until the no more messages at an earlier point in time have to be processed. - * - * @param duration The duration of simulation time to wait before resuming execution. - * @param queue The mutable queue to push the messages to. - */ - suspend fun wait(duration: Duration, queue: Queue<Any>) - - /** - * Suspend the [Process] of the [Entity] in simulation for one tick in simulation time which is defined by the - * [Clock]. - * - * @return `true` to allow usage in while statements. - */ - suspend fun tick(): Boolean -} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Interrupt.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Interrupt.kt deleted file mode 100644 index de7c5c6c..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Interrupt.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel - -/** - * An [Interrupt] message is sent to a [Process] in order to interrupt its suspended state. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -object Interrupt: Throwable("The process has been interrupted by another entity") diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Kernel.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Kernel.kt deleted file mode 100644 index ffb6299c..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Kernel.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel - -import nl.atlarge.opendc.topology.MutableTopology -import nl.atlarge.opendc.topology.Topology - -/** - * A message-based discrete event simulator (DES). This interface allows running simulations over a [Topology]. - * This discrete event simulator works by having entities in a [Topology] interchange messages between each other and - * updating their observable state accordingly. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Kernel { - /** - * The name of the kernel. - */ - val name: String - - /** - * Create a new [Simulation] of the given [Topology] that is facilitated by this simulation kernel. - * - * @param topology The [Topology] to create a [Simulation] of. - * @return A [Simulation] instance. - */ - fun create(topology: MutableTopology): Simulation -} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Process.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Process.kt deleted file mode 100644 index 40fbefbf..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Process.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel - -import nl.atlarge.opendc.topology.Entity - -/** - * A [Process] defines the behaviour of an [Entity] within simulation. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Process<in E : Entity<*>> { - /** - * This method is invoked to start the simulation an [Entity] associated with this [Process]. - * - * This method is assumed to be running during a simulation, but should hand back control to the simulator at - * some point by suspending the process. This allows other processes to do work in the current tick of the - * simulation. - * Suspending the process can be achieved by calling suspending method in the context: - * - [Context.tick] - Wait for the next tick to occur - * - [Context.wait] - Wait for `n` amount of ticks before resuming execution. - * - [Context.receive] - Wait for a message to be received in the mailbox of the [Entity] before resuming - * execution. - * - * If this method exits early, before the simulation has finished, the entity is assumed to be shutdown and its - * simulation will not run any further. - */ - suspend fun Context<E>.run() -} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Envelope.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Envelope.kt deleted file mode 100644 index 608d325f..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Envelope.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel.messaging - -import nl.atlarge.opendc.topology.Entity - -/** - * The envelope of a message that is sent to an [Entity], also containing the metadata of the message. - * - * @param T The shape of the message inside the envelope. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Envelope<out T: Any> { - /** - * The message in this envelope. - */ - val message: T - - /** - * The sender of the message. - */ - val sender: Entity<*>? - - /** - * The destination of the message. - */ - val destination: Entity<*> -} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Readable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Readable.kt deleted file mode 100644 index 398e9697..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Readable.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel.messaging - -import nl.atlarge.opendc.kernel.time.Duration - - -/** - * A [Readable] instance has a mailbox associated with the instance to which objects can send messages, which can be - * received by the class. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Readable { - /** - * Retrieve and removes a single message from the entity's mailbox, suspending the function if the mailbox is empty. - * The execution is resumed after the message has landed in the entity's mailbox after which the message [Envelope] - * is mapped through `block` to generate a processed message. - * - * @param block The block to process the message with. - * @return The processed message. - */ - suspend fun <T> receive(block: suspend Envelope<*>.(Any) -> T): T - - /** - * Retrieve and removes a single message from the entity's mailbox, suspending the function if the mailbox is empty. - * The execution is resumed after the message has landed in the entity's mailbox or the timeout was reached, - * - * If the message has been received, the message [Envelope] is mapped through `block` to generate a processed - * message. If the timeout was reached, `block` is not called and `null` is returned. - * - * @param timeout The duration to wait before resuming execution. - * @param block The block to process the message with. - * @return The processed message or `null` if the timeout was reached. - */ - suspend fun <T> receive(timeout: Duration, block: suspend Envelope<*>.(Any) -> T): T? - - /** - * Retrieve and removes a single message from the entity's mailbox, suspending the function until a message has - * landed in the entity's mailbox. - * - * @return The message that was received from the entity's mailbox. - */ - suspend fun receive(): Any = receive { it } - - /** - * Retrieve and removes a single message from the entity's mailbox, suspending the function until a message has - * landed in the entity's mailbox or the timeout has been reached. - * - * @return The message that was received from the entity's mailbox or `null` if the timeout was reached. - */ - suspend fun receive(timeout: Duration): Any? = receive(timeout) { it } -} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Receipt.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Receipt.kt deleted file mode 100644 index 74433f5e..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Receipt.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel.messaging - -import nl.atlarge.opendc.kernel.Kernel -import nl.atlarge.opendc.topology.Entity - -/** - * A receipt of a message that has been scheduled by a simulation [Kernel]. This interface allows the cancellation of a - * message that has been scheduled for delivery and for checking the status of a delivery. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Receipt { - /** - * A flag to indicate the message has been canceled. - */ - val canceled: Boolean - - /** - * A flag to indicate the message has been delivered. - */ - val delivered: Boolean - - /** - * Cancel the message to prevent it from being received by an [Entity]. - * - * @throws IllegalStateException if the message has already been delivered. - */ - fun cancel() -} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Writable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Writable.kt deleted file mode 100644 index 0d2b2725..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Writable.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel.messaging - -import nl.atlarge.opendc.kernel.time.Duration -import nl.atlarge.opendc.topology.Entity - -/** - * A [Writable] instance allows entities to send messages. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Writable { - /** - * Send the given message to the specified entity. - * - * @param msg The message to send. - * @param delay The amount of time to wait before the message should be received. - * @return A [Receipt] of the message that has been sent. - */ - suspend fun Entity<*>.send(msg: Any, delay: Duration = 0): Receipt - - /** - * Send the given message to the specified entity. - * - * @param msg The message to send. - * @param sender The sender of the message. - * @param delay The amount of time to wait before the message should be received. - * @return A [Receipt] of the message that has been sent. - */ - suspend fun Entity<*>.send(msg: Any, sender: Entity<*>, delay: Duration = 0): Receipt -} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/sampler/Sampler.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/sampler/Sampler.kt deleted file mode 100644 index 66c33341..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/sampler/Sampler.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel.sampler - -/** - * A sampler generates data points (samples) of the simulation based on the events that occur to [Entity] instances that - * are part of the simulation. - * - * <p>[Sampler]s work by observing [Entity] instances in the simulation and transforming this stream of events into a - * stream of data points. - * - * <p>An example would be a sampler that tracks [Machine] occupation per time unit, which is achieved by observing the - * [Entity]'s event stream and filtering for [JobAssignment] events. - * - * @param <T> The data type of result generated by this sampler. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Sampler<out T> diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/Clock.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/Clock.kt deleted file mode 100644 index f03a98fa..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/Clock.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel.time - -import nl.atlarge.opendc.kernel.Simulation - -/** - * A clock controls and provides access to the simulation time of a [Simulation]. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Clock { - /** - * The moment in time the clock is currently at. - */ - val now: Instant - - /** - * The duration of a tick in this clock. This is an arbitrary duration of time in which entities in simulation - * perform some defined amount of work. - */ - val tick: Duration - - /** - * Advance the clock by the given duration. - * - * @param duration The duration to advance the clock by. - */ - fun advance(duration: Duration) { - require(duration >= 0) { "The duration to advance the clock must not be a negative number" } - advanceTo(now + duration) - } - - /** - * Rewind the clock by the given duration. - * - * @param duration The duration to rewind the clock by. - */ - fun rewind(duration: Duration) { - require(duration >= 0) { "The duration to rewind the clock must not be a negative number" } - rewindTo(now - duration) - } - - /** - * Rewind the clock to the given point in time. - * - * @param instant The point in time to rewind the clock to. - */ - fun rewindTo(instant: Instant) - - /** - * Advance the clock to the given point in time. - * - * @param instant The point in time to advance the clock to. - */ - fun advanceTo(instant: Instant) -} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/TickClock.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/TickClock.kt deleted file mode 100644 index d960f454..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/time/TickClock.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel.time - -/** - * A tick based clock which divides time into a discrete interval of points. - * - * @param initial The initial point in time of the clock. - * @param tick The duration of a tick. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -class TickClock(initial: Instant = 0, override val tick: Duration = 1) : Clock { - /** - * The moment in time the clock is currently at. - */ - override var now: Instant = initial - private set - - /** - * Advance the clock to the given point in time. - * - * @param instant The moment in time to advance the clock to. - */ - override fun advanceTo(instant: Instant) { - require(instant >= now) { "The point to advance to must be at the same point or further than now" } - now = instant - } - - /** - * Rewind the clock to the given point in time. - * - * @param instant The point in time to rewind the clock to. - */ - override fun rewindTo(instant: Instant) { - require(now >= instant) { "The point to rewind to must be before the current point in time" } - now = instant - } -} diff --git a/opendc-omega/build.gradle b/opendc-kernel-omega/build.gradle index 89b5740d..ea463f5a 100644 --- a/opendc-omega/build.gradle +++ b/opendc-kernel-omega/build.gradle @@ -24,7 +24,7 @@ /* Build configuration */ buildscript { - ext.kotlin_version = '1.1.4-3' + ext.kotlin_version = '1.2.10' ext.dokka_version = '0.9.15' repositories { @@ -68,8 +68,8 @@ dokka { } /* Project configuration */ -group 'nl.atlarge.opendc' -version '1.0' +group 'com.atlarge.opendc' +version '1.1' repositories { jcenter() @@ -83,5 +83,4 @@ dependencies { testRuntime "org.junit.jupiter:junit-jupiter-engine:5.0.0-RC3" testCompile "org.junit.platform:junit-platform-launcher:1.0.0-RC3" testCompile "org.slf4j:slf4j-simple:1.7.25" - testCompile project(':opendc-stdlib') } diff --git a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/MessageContainer.kt b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/MessageContainer.kt index 1554a9e6..af13d1fd 100644 --- a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/MessageContainer.kt +++ b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/MessageContainer.kt @@ -22,12 +22,11 @@ * SOFTWARE. */ -package nl.atlarge.opendc.kernel.omega +package com.atlarge.opendc.omega -import nl.atlarge.opendc.kernel.messaging.Envelope -import nl.atlarge.opendc.kernel.messaging.Receipt -import nl.atlarge.opendc.kernel.time.Instant -import nl.atlarge.opendc.topology.Entity +import com.atlarge.opendc.simulator.Instant +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.simulator.Envelope /** * A wrapper around a message that has been scheduled for processing. @@ -40,29 +39,10 @@ import nl.atlarge.opendc.topology.Entity */ internal data class MessageContainer(override val message: Any, val time: Instant, - override val sender: Entity<*>?, - override val destination: Entity<*>) : Envelope<Any>, Receipt { + override val sender: Entity<*, *>?, + override val destination: Entity<*, *>) : Envelope<Any> { /** * A flag to indicate the message has been canceled. */ - override var canceled: Boolean = false - - /** - * A flag to indicate the message has been delivered. - */ - override var delivered: Boolean = false - - /** - * Cancel the message to prevent it from being received by an [Entity]. - * - * @throws IllegalStateException if the message has already been delivered. - */ - override fun cancel() { - if (delivered) { - throw IllegalStateException("The message has already been delivered") - } - - canceled = true - } - + internal var canceled: Boolean = false } diff --git a/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaKernel.kt b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaKernel.kt new file mode 100644 index 00000000..fb5ce24b --- /dev/null +++ b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaKernel.kt @@ -0,0 +1,315 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.omega + +import com.atlarge.opendc.simulator.* +import com.atlarge.opendc.simulator.kernel.Kernel +import com.atlarge.opendc.simulator.Bootstrap +import mu.KotlinLogging +import java.util.* +import kotlin.coroutines.experimental.* + +/** + * The Omega simulation kernel is the reference simulation kernel implementation for the OpenDC Simulator core. + * + * This simulator implementation is a single-threaded implementation, running simulation kernels synchronously and + * provides a single priority queue for all events (messages, ticks, etc) that occur in the entities. + * + * @property model The model that is simulated. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +internal class OmegaKernel<M>(bootstrap: Bootstrap<M>) : Kernel<M>, Bootstrap.Context<M> { + /** + * The logger instance to use for the simulator. + */ + private val logger = KotlinLogging.logger {} + + /** + * The registry of the simulation kernels used in the experiment. + */ + private val registry: MutableMap<Entity<*, *>, OmegaContext<*>> = HashMap() + + /** + * The message queue. + */ + private val queue: Queue<MessageContainer> = PriorityQueue(Comparator.comparingLong(MessageContainer::time)) + + /** + * The simulation time. + */ + override var time: Instant = 0 + + /** + * The model of simulation. + */ + override val model: M = bootstrap.bootstrap(this) + + override val <E : Entity<S, *>, S> E.state: S + get() = context?.state ?: initialState + + /** + * The context associated with an [Entity]. + */ + @Suppress("UNCHECKED_CAST") + private val <E : Entity<S, M>, S, M> E.context: OmegaContext<S>? + get() = registry[this] as? OmegaContext<S> + + override fun register(entity: Entity<*, M>): Boolean { + if (!registry.containsKey(entity) && entity !is Process) { + return false + } + + @Suppress("UNCHECKED_CAST") + val process = entity as Process<Any, M> + val context = OmegaContext(entity).also { registry.put(entity, it) } + + // Bootstrap the process coroutine + val block: suspend () -> Unit = { process.run { context.run() } } + block.startCoroutine(context) + + return true + } + + override fun deregister(entity: Entity<*, M>): Boolean { + val context = entity.context ?: return false + context.resume(Unit) + return true + } + + override fun schedule(message: Any, destination: Entity<*, *>, sender: Entity<*, *>?, delay: Duration) = + schedule(prepare(message, destination, sender, delay)) + + override fun step() { + while (true) { + val envelope = queue.peek() ?: return + val delivery = envelope.time + + if (delivery > time) { + // Tick has yet to occur + // Jump in time to next event + time = delivery + break + } else if (delivery < time) { + // Tick has already occurred + logger.warn { "message processed out of order" } + } + + queue.poll() + + // If the sender has canceled the message, we move on to the next message + if (envelope.canceled) { + continue + } + + val context = envelope.destination.context ?: continue + + if (envelope.message !is Interrupt) { + context.continuation.resume(envelope) + } else { + context.continuation.resumeWithException(envelope.message) + } + + context.last = time + } + } + + + override fun run() { + while (queue.isNotEmpty()) { + step() + } + } + + override fun run(until: Instant) { + require(until > 0) { "The given instant must be a non-zero positive number" } + + if (time >= until) { + return + } + + while (time < until && queue.isNotEmpty()) { + step() + } + + // Fix clock if step() jumped too far in time to give the impression to the user that simulation stopped at + // exactly the tick it gave. This has not effect on the actual simulation results as the next call to run() will + // just jump forward again. + if (time > until) { + time = until + } + } + + private fun schedule(envelope: MessageContainer) { + queue.add(envelope) + } + + private fun prepare(message: Any, destination: Entity<*, *>, sender: Entity<*, *>? = null, + delay: Duration): MessageContainer { + require(delay >= 0) { "The amount of time to delay the message must be a positive number" } + return MessageContainer(message, time + delay, sender, destination) + } + + /** + * This internal class provides the default implementation for the [Context] interface for this simulator. + */ + private inner class OmegaContext<S>(val process: Process<S, M>) : Context<S, M>, Continuation<Unit> { + /** + * The continuation to resume the execution of the process. + */ + lateinit var continuation: Continuation<Envelope<*>> + + /** + * The last point in time the process has done some work. + */ + var last: Instant = -1 + + /** + * The model in which the process exists. + */ + override val model: M + get() = this@OmegaKernel.model + + /** + * The state of the entity. + */ + override var state: S = process.initialState + + /** + * The current point in simulation time. + */ + override val time: Instant + get() = this@OmegaKernel.time + + /** + * The duration between the current point in simulation time and the last point in simulation time where the + * [Context] has executed some work. + */ + override val delta: Duration + get() = maxOf(time - last, 0) + + /** + * The [CoroutineContext] for a [Context]. + */ + override val context: CoroutineContext = EmptyCoroutineContext + + /** + * The observable state of an [Entity] within the simulation is provided by the context of the simulation. + */ + override val <T : Entity<S, *>, S> T.state: S + get() = context?.state ?: initialState + + /** + * Retrieve and remove and single message from the mailbox of the [Entity] and suspend the [Context] until the + * message has been received. + * + * @return The envelope containing the message. + */ + suspend fun receiveEnvelope(): Envelope<*> = suspendCoroutine { continuation = it } + + suspend override fun <T> receive(transform: suspend Envelope<*>.(Any) -> T): T { + val envelope = receiveEnvelope() + return transform(envelope, envelope.message) + } + + + suspend override fun <T> receive(timeout: Duration, transform: suspend Envelope<*>.(Any) -> T): T? { + val send = prepare(Timeout, process, process, timeout).also { schedule(it) } + + try { + val received = receiveEnvelope() + + if (received.message !is Timeout) { + send.canceled = true + return transform(received, received.message) + } + + return null + } finally { + send.canceled = true + } + } + + suspend override fun Entity<*, *>.send(msg: Any, delay: Duration) = send(msg, process, delay) + + suspend override fun Entity<*, *>.send(msg: Any, sender: Entity<*, *>, delay: Duration) = + schedule(prepare(msg, sender, delay = delay)) + + suspend override fun Entity<*, *>.interrupt() = send(Interrupt) + + suspend override fun hold(duration: Duration) { + require(duration >= 0) { "The amount of time to hold must be a positive number" } + val envelope = prepare(Resume, process, process, duration).also { schedule(it) } + + try { + while (true) { + if (receive() is Resume) + return + } + } finally { + envelope.canceled = true + } + } + + suspend override fun hold(duration: Duration, queue: Queue<Any>) { + require(duration >= 0) { "The amount of time to hold must be a positive number" } + val envelope = prepare(Resume, process, process, duration).also { schedule(it) } + + try { + while (true) { + val msg = receive() + if (msg is Resume) + return + queue.add(msg) + } + } finally { + envelope.canceled = true + } + } + + + // Completion continuation implementation + /** + * Resume the execution of this continuation with the given value. + * + * @param value The value to resume with. + */ + override fun resume(value: Unit) { + // Deregister process from registry in order to have the GC collect this context + registry.remove(process) + } + + /** + * Resume the execution of this continuation with an exception. + * + * @param exception The exception to resume with. + */ + override fun resumeWithException(exception: Throwable) { + // Deregister process from registry in order to have the GC collect this context:w + registry.remove(process) + + logger.error(exception) { "An exception occurred during the execution of a process" } + } + } +} diff --git a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaKernel.kt b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaKernelFactory.kt index cbc25b63..dcad4dce 100644 --- a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaKernel.kt +++ b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaKernelFactory.kt @@ -22,14 +22,11 @@ * SOFTWARE. */ -package nl.atlarge.opendc.kernel.omega +package com.atlarge.opendc.omega -import nl.atlarge.opendc.kernel.Kernel -import nl.atlarge.opendc.kernel.Process -import nl.atlarge.opendc.kernel.Simulation -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.MutableTopology -import nl.atlarge.opendc.topology.Topology +import com.atlarge.opendc.simulator.kernel.KernelFactory +import com.atlarge.opendc.simulator.kernel.Kernel +import com.atlarge.opendc.simulator.Bootstrap /** * The Omega simulation kernel is the reference simulation kernel implementation for the OpenDC Simulator core. @@ -37,22 +34,14 @@ import nl.atlarge.opendc.topology.Topology * This simulator implementation is a single-threaded implementation, running simulation kernels synchronously and * provides a single priority queue for all events (messages, ticks, etc) that occur in the entities. * - * By default, [Process]s are resolved as part of the [Topology], meaning each [Entity] in the topology should also - * implement its simulation behaviour by deriving from the [Process] interface. - * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -object OmegaKernel : Kernel { - /** - * The name of the kernel. - */ - override val name: String = "opendc-omega" - +object OmegaKernelFactory : KernelFactory { /** - * Create a new [Simulation] of the given [Topology] that is facilitated by this simulation kernel. + * Create a simulation over the given model facilitated by this simulation kernel. * - * @param topology The [Topology] to create a [Simulation] of. - * @return A [Simulation] instance. + * @param bootstrap The bootstrap procedure to bootstrap the simulation with. + * @return A [Kernel] instance to control the simulation. */ - override fun create(topology: MutableTopology): Simulation = OmegaSimulation(this, topology) + override fun <M> create(bootstrap: Bootstrap<M>): Kernel<M> = OmegaKernel(bootstrap) } diff --git a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/Resume.kt b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/Resume.kt index d20115d0..d4bd8536 100644 --- a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/Resume.kt +++ b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/Resume.kt @@ -22,9 +22,10 @@ * SOFTWARE. */ -package nl.atlarge.opendc.kernel.omega +package com.atlarge.opendc.omega -import nl.atlarge.opendc.kernel.Context +import com.atlarge.opendc.simulator.Context +import com.atlarge.opendc.simulator.Process /** * An internal message used by the Omega simulation kernel to indicate to a suspended [Process], that it should wake up diff --git a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/Timeout.kt b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/Timeout.kt index 41dcce71..c205f6b5 100644 --- a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/Timeout.kt +++ b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/Timeout.kt @@ -22,7 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.kernel.omega +package com.atlarge.opendc.omega + +import com.atlarge.opendc.simulator.Process /** * An internal message used by the Omega simulation kernel to indicate to a suspended [Process], that a timeout has been diff --git a/opendc-omega/src/test/kotlin/nl/atlarge/opendc/SmokeTest.kt b/opendc-kernel-omega/src/test/kotlin/com/atlarge/opendc/omega/SmokeTest.kt index cb2ce643..b358d618 100644 --- a/opendc-omega/src/test/kotlin/nl/atlarge/opendc/SmokeTest.kt +++ b/opendc-kernel-omega/src/test/kotlin/com/atlarge/opendc/omega/SmokeTest.kt @@ -22,14 +22,11 @@ * SOFTWARE. */ -package nl.atlarge.opendc +package com.atlarge.opendc.omega -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.kernel.Process -import nl.atlarge.opendc.kernel.omega.OmegaKernel -import nl.atlarge.opendc.topology.AdjacencyList -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.machine.Machine +import com.atlarge.opendc.simulator.Context +import com.atlarge.opendc.simulator.Process +import com.atlarge.opendc.simulator.Bootstrap import org.junit.jupiter.api.Test /** @@ -38,78 +35,82 @@ import org.junit.jupiter.api.Test * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ internal class SmokeTest { + class EchoProcess : Process<Unit, Unit> { + override val initialState = Unit + suspend override fun Context<Unit, Unit>.run() { + while (true) { + receive { + sender?.send(message) + } + } + } + } + /** * Run a large amount of simulations and test if any exceptions occur. */ @Test fun smoke() { val n = 1000 - val builder = AdjacencyList.builder() - repeat(n) { - val root = Machine() - val topology = builder.construct { - add(root) - - val other = Machine() - add(other) - - connect(root, other, tag = "neighbour") - connect(other, root, tag = "neighbour") + val messages = 100 + val bootstrap: Bootstrap<Unit> = Bootstrap.create { ctx -> + repeat(n) { + EchoProcess().also { + ctx.register(it) + + for (i in 1 until messages) { + ctx.schedule(i, it, delay = i.toLong()) + } + } } - - val simulation = OmegaKernel.create(topology) - - for (i in 1..1000) { - simulation.schedule(i, root, delay = i.toLong()) - } - - simulation.run() } + val kernel = OmegaKernelFactory.create(bootstrap) + kernel.run() } - class NullProcess : Entity<Unit>, Process<NullProcess> { + class NullProcess : Process<Unit, Unit> { override val initialState = Unit - suspend override fun Context<NullProcess>.run() {} + suspend override fun Context<Unit, Unit>.run() {} } /** - * Test if the kernel allows sending messages to [Process] instances that have already stopped. + * Test if the kernel allows sending messages to [Context] instances that have already stopped. */ @Test fun `sending message to process that has gracefully stopped`() { - - val builder = AdjacencyList.builder() val process = NullProcess() - val topology = builder.construct { - add(process) + val bootstrap: Bootstrap<Unit> = Bootstrap.create { ctx -> + process.also { + ctx.register(it) + ctx.schedule(0, it) + } } - val simulation = OmegaKernel.create(topology) - simulation.schedule(0, process) - simulation.run() + val kernel = OmegaKernelFactory.create(bootstrap) + kernel.run() } - class CrashProcess : Entity<Unit>, Process<NullProcess> { + class CrashProcess : Process<Unit, Unit> { override val initialState = Unit - suspend override fun Context<NullProcess>.run() { - TODO() + suspend override fun Context<Unit, Unit>.run() { + TODO("This process should crash") } } /** - * Test if the kernel allows sending messages to [Process] instances that have crashed. + * Test if the kernel allows sending messages to [Context] instances that have crashed. */ @Test fun `sending message to process that has crashed`() { - - val builder = AdjacencyList.builder() val process = CrashProcess() - val topology = builder.construct { - add(process) + val bootstrap: Bootstrap<Unit> = Bootstrap.create { ctx -> + process.also { + ctx.register(it) + ctx.schedule(0, it) + } } - val simulation = OmegaKernel.create(topology) - simulation.schedule(0, process) - simulation.run() + val kernel = OmegaKernelFactory.create(bootstrap) + kernel.run() } } diff --git a/opendc-model-odc/core/build.gradle b/opendc-model-odc/core/build.gradle new file mode 100644 index 00000000..c8336196 --- /dev/null +++ b/opendc-model-odc/core/build.gradle @@ -0,0 +1,87 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Build configuration */ +buildscript { + ext.kotlin_version = '1.2.10' + ext.dokka_version = '0.9.15' + + repositories { + mavenCentral() + jcenter() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version" + classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0-RC3' + } +} + +apply plugin: 'java' +apply plugin: 'kotlin' +apply plugin: 'org.jetbrains.dokka' +apply plugin: 'org.junit.platform.gradle.plugin' + +compileKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} + +compileTestKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} + +kotlin { + experimental { + coroutines 'enable' + } +} + +dokka { + outputFormat = 'html' + outputDirectory = "$buildDir/javadoc" +} + +/* Project configuration */ +group 'com.atlarge.opendc' +version '1.1' + +repositories { + jcenter() +} + +dependencies { + compile project(':opendc-core') + compile project(':opendc-stdlib') + compile "io.github.microutils:kotlin-logging:1.4.6" + + testCompile "org.junit.jupiter:junit-jupiter-api:5.0.0-RC3" + testRuntime "org.junit.jupiter:junit-jupiter-engine:5.0.0-RC3" + testCompile "org.junit.platform:junit-platform-launcher:1.0.0-RC3" + testCompile "org.slf4j:slf4j-simple:1.7.25" +} diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/OdcModel.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/OdcModel.kt new file mode 100644 index 00000000..01ffbd2c --- /dev/null +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/OdcModel.kt @@ -0,0 +1,10 @@ +package com.atlarge.opendc.model.odc + +import com.atlarge.opendc.model.topology.MutableTopology + +/** + * The OpenDC standard simulation model used for datacenter simulations. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface OdcModel: MutableTopology diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/FifoScheduler.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/FifoScheduler.kt index 6f5db211..d2cbcdfe 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/FifoScheduler.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/FifoScheduler.kt @@ -22,13 +22,11 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.scheduler +package com.atlarge.opendc.model.odc.platform.scheduler -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.platform.workload.Job -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.machine.Machine -import nl.atlarge.opendc.platform.workload.Task +import com.atlarge.opendc.simulator.Context +import com.atlarge.opendc.model.odc.platform.workload.Task +import com.atlarge.opendc.model.odc.topology.machine.Machine import java.util.* /** @@ -55,7 +53,7 @@ class FifoScheduler : Scheduler { /** * (Re)schedule the tasks submitted to the scheduler over the specified set of machines. */ - override suspend fun <E : Entity<*>> Context<E>.schedule() { + override suspend fun <S, M> Context<S, M>.schedule() { if (queue.isEmpty()) { return } diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/Scheduler.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/Scheduler.kt index 578bef9c..ee965af9 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/Scheduler.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/Scheduler.kt @@ -22,12 +22,12 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.scheduler +package com.atlarge.opendc.model.odc.platform.scheduler -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.platform.workload.Task -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.machine.Machine +import com.atlarge.opendc.simulator.Context +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.model.odc.platform.workload.Task +import com.atlarge.opendc.model.odc.topology.machine.Machine /** * A task scheduler that is coupled to an [Entity] in the topology of the cloud network. @@ -46,7 +46,7 @@ interface Scheduler { * This method should be invoked at some interval to allow the scheduler to reschedule existing tasks and schedule * new tasks. */ - suspend fun <E: Entity<*>> Context<E>.schedule() + suspend fun <S, M> Context<S, M>.schedule() /** * Submit a [Task] to this scheduler. diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/SrtfScheduler.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/SrtfScheduler.kt index 1fbf8c04..0e497b56 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/scheduler/SrtfScheduler.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/SrtfScheduler.kt @@ -22,12 +22,11 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.scheduler +package com.atlarge.opendc.model.odc.platform.scheduler -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.platform.workload.Task -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.machine.Machine +import com.atlarge.opendc.simulator.Context +import com.atlarge.opendc.model.odc.platform.workload.Task +import com.atlarge.opendc.model.odc.topology.machine.Machine import java.util.* /** @@ -54,7 +53,7 @@ class SrtfScheduler : Scheduler { /** * (Re)schedule the tasks submitted to the scheduler over the specified set of machines. */ - override suspend fun <E : Entity<*>> Context<E>.schedule() { + override suspend fun <S, M> Context<S, M>.schedule() { if (tasks.isEmpty()) { return } diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Job.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Job.kt index df2f2b6a..c42bb667 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Job.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Job.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.workload +package com.atlarge.opendc.model.odc.platform.workload /** * A bag of tasks which are submitted by a [User] to the cloud network. diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Task.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Task.kt index e740cdd8..f7b9d60f 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Task.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Task.kt @@ -22,10 +22,10 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.workload +package com.atlarge.opendc.model.odc.platform.workload -import nl.atlarge.opendc.kernel.time.Instant -import nl.atlarge.opendc.topology.machine.Machine +import com.atlarge.opendc.simulator.Instant +import com.atlarge.opendc.model.odc.topology.machine.Machine /** * A task that runs as part of a [Job] on a [Machine]. diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/TaskState.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/TaskState.kt index d1f908af..2fb3acd9 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/TaskState.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/TaskState.kt @@ -22,9 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.workload +package com.atlarge.opendc.model.odc.platform.workload -import nl.atlarge.opendc.kernel.time.Instant +import com.atlarge.opendc.simulator.Instant /** diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Trace.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Trace.kt index 6dd2efb8..b2d65277 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/Trace.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Trace.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.workload +package com.atlarge.opendc.model.odc.platform.workload /** * A timestamped sequence of jobs received in a cloud network. diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/User.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/User.kt index d827fee5..6099db3e 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/platform/workload/User.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/User.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform.workload +package com.atlarge.opendc.model.odc.platform.workload /** * A user of a cloud network that provides [Job]s for the simulation. diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Datacenter.kt index f7eb29d8..2b682410 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Datacenter.kt @@ -22,17 +22,18 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.container +package com.atlarge.opendc.model.odc.topology.container import mu.KotlinLogging -import nl.atlarge.opendc.topology.destinations -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.kernel.Process -import nl.atlarge.opendc.kernel.time.Duration -import nl.atlarge.opendc.platform.scheduler.Scheduler -import nl.atlarge.opendc.platform.workload.Task -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.machine.Machine +import com.atlarge.opendc.simulator.Context +import com.atlarge.opendc.simulator.Duration +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.simulator.Process +import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler +import com.atlarge.opendc.model.odc.platform.workload.Task +import com.atlarge.opendc.model.odc.topology.machine.Machine +import com.atlarge.opendc.model.topology.Topology +import com.atlarge.opendc.model.topology.destinations import java.util.* /** @@ -42,7 +43,7 @@ import java.util.* * @property interval The interval at which task will be (re)scheduled. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Datacenter : Entity<Unit>, Process<Datacenter> { +interface Datacenter : Process<Unit, Topology> { /** * The task scheduler the datacenter uses. */ @@ -54,21 +55,20 @@ interface Datacenter : Entity<Unit>, Process<Datacenter> { val interval: Duration /** - * This method is invoked to start the simulation an [Entity] associated with this [Process]. + * This method is invoked to start the simulation an [Entity] associated with this [Context]. * * This method is assumed to be running during a simulation, but should hand back control to the simulator at * some point by suspending the process. This allows other processes to do work in the current tick of the * simulation. * Suspending the process can be achieved by calling suspending method in the context: - * - [Context.tick] - Wait for the next tick to occur - * - [Context.wait] - Wait for `n` amount of ticks before resuming execution. + * - [Context.hold] - Wait for `n` amount of ticks before resuming execution. * - [Context.receive] - Wait for a message to be received in the mailbox of the [Entity] before resuming * execution. * * If this method exits early, before the simulation has finished, the entity is assumed to be shutdown and its * simulation will not run any further. */ - suspend override fun Context<Datacenter>.run() { + suspend override fun Context<Unit, Topology>.run() = model.run { val logger = KotlinLogging.logger {} // The queue of messages to be processed after a cycle @@ -84,7 +84,7 @@ interface Datacenter : Entity<Unit>, Process<Datacenter> { machines.forEach(scheduler::register) while (true) { - // Process all messages in the queue + // Context all messages in the queue while (queue.isNotEmpty()) { val msg = queue.poll() if (msg is Task) { @@ -96,7 +96,7 @@ interface Datacenter : Entity<Unit>, Process<Datacenter> { scheduler.run { schedule() } // Sleep a time quantum - wait(interval, queue) + hold(interval, queue) } } } diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Rack.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Rack.kt index 25429f71..0ec43f9a 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Rack.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Rack.kt @@ -22,9 +22,10 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.container +package com.atlarge.opendc.model.odc.topology.container -import nl.atlarge.opendc.topology.Entity +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.model.topology.Topology /** * A type of physical steel and electronic framework that is designed to house servers, networking devices, cables and @@ -32,4 +33,4 @@ import nl.atlarge.opendc.topology.Entity * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Rack : Entity<Unit> +interface Rack : Entity<Unit, Topology> diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Room.kt index 3b338899..50cfc3e6 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Room.kt @@ -22,13 +22,14 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.container +package com.atlarge.opendc.model.odc.topology.container -import nl.atlarge.opendc.topology.Entity +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.model.topology.Topology /** * A physical room in a datacenter with relationships to the entities within the room. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Room : Entity<Unit> +interface Room : Entity<Unit, Topology> diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Cpu.kt index f97e73e9..58eacdc1 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Cpu.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.machine +package com.atlarge.opendc.model.odc.topology.machine /** * A central processing unit. diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Gpu.kt index 15c5263f..84afc711 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Gpu.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.machine +package com.atlarge.opendc.model.odc.topology.machine /** * A graphics processing unit. diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Machine.kt index b5016adb..4f4ce645 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Machine.kt @@ -22,15 +22,15 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.machine +package com.atlarge.opendc.model.odc.topology.machine +import com.atlarge.opendc.simulator.Context +import com.atlarge.opendc.simulator.Process +import com.atlarge.opendc.model.odc.platform.workload.Task +import com.atlarge.opendc.model.topology.Topology +import com.atlarge.opendc.model.topology.destinations +import com.atlarge.opendc.simulator.Duration import mu.KotlinLogging -import nl.atlarge.opendc.topology.destinations -import nl.atlarge.opendc.platform.workload.Task -import nl.atlarge.opendc.kernel.Context -import nl.atlarge.opendc.kernel.Process -import nl.atlarge.opendc.kernel.time.Duration -import nl.atlarge.opendc.topology.Entity /** * A Physical Machine (PM) inside a rack of a datacenter. It has a speed, and can be given a workload on which it will @@ -38,7 +38,7 @@ import nl.atlarge.opendc.topology.Entity * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -open class Machine : Entity<Machine.State>, Process<Machine> { +open class Machine : Process<Machine.State, Topology> { /** * The logger instance to use for the simulator. */ @@ -74,8 +74,8 @@ open class Machine : Entity<Machine.State>, Process<Machine> { /** * Run the simulation kernel for this entity. */ - override suspend fun Context<Machine>.run() { - update(State(Status.IDLE)) + override suspend fun Context<State, Topology>.run() = model.run { + state = State(Status.IDLE) val interval: Duration = 10 val cpus = outgoingEdges.destinations<Cpu>("cpu") @@ -83,17 +83,17 @@ open class Machine : Entity<Machine.State>, Process<Machine> { // Halt the machine if it has not processing units (see bug #4) if (cpus.isEmpty()) { - update(State(Status.HALT)) + state = State(Status.HALT) return } var task: Task = receiveTask() - update(State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0)) + state = State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0) while (true) { if (task.finished) { - logger.info { "${entity.id}: Task ${task.id} finished. Machine idle at $time" } - update(State(Status.IDLE)) + logger.info { "$id: Task ${task.id} finished. Machine idle at $time" } + state = State(Status.IDLE) task = receiveTask() } else { task.consume(time, speed * delta) @@ -103,17 +103,17 @@ open class Machine : Entity<Machine.State>, Process<Machine> { val msg = receive(interval) if (msg is Task) { task = msg - update(State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0)) + state = State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0) } } } /** - * Wait for a [Task] to be received by the [Process] and discard all other messages received in the meantime. + * Wait for a [Task] to be received by the [Context] and discard all other messages received in the meantime. * * @return The task that has been received. */ - private suspend fun Context<Machine>.receiveTask(): Task { + private suspend fun Context<State, Topology>.receiveTask(): Task { while (true) { val msg = receive() if (msg is Task) diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/ProcessingUnit.kt index abc8608b..0b8989de 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/ProcessingUnit.kt @@ -22,16 +22,17 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.machine +package com.atlarge.opendc.model.odc.topology.machine -import nl.atlarge.opendc.topology.Entity +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.model.topology.Topology /** * An interface representing a generic processing unit which is placed into a [Machine]. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface ProcessingUnit : Entity<Unit> { +interface ProcessingUnit : Entity<Unit, Topology> { /** * The speed of this [ProcessingUnit] per core in MHz. */ diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/network/NetworkUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/network/NetworkUnit.kt index d3a9eefe..a41a8326 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/network/NetworkUnit.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/network/NetworkUnit.kt @@ -22,13 +22,14 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.network +package com.atlarge.opendc.model.odc.topology.network -import nl.atlarge.opendc.topology.Entity +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.model.topology.Topology /** * A generic interface for a network unit in a cloud network. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface NetworkUnit : Entity<Unit> +interface NetworkUnit : Entity<Unit, Topology> diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/power/PowerUnit.kt index b9602e55..8650b5dc 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/power/PowerUnit.kt @@ -22,13 +22,14 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.power +package com.atlarge.opendc.model.odc.topology.power -import nl.atlarge.opendc.topology.Entity +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.model.topology.Topology /** * An [Entity] which provides power for other entities a cloud network to run. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface PowerUnit : Entity<Unit> +interface PowerUnit : Entity<Unit, Topology> diff --git a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/storage/StorageUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/storage/StorageUnit.kt index f719f152..b5bb4dfb 100644 --- a/opendc-stdlib/src/main/kotlin/nl/atlarge/opendc/topology/storage/StorageUnit.kt +++ b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/storage/StorageUnit.kt @@ -22,13 +22,14 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.storage +package com.atlarge.opendc.model.odc.topology.storage -import nl.atlarge.opendc.topology.Entity +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.model.topology.Topology /** * A generic interface for a storage unit in a cloud network. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface StorageUnit : Entity<Unit> +interface StorageUnit : Entity<Unit, Topology> diff --git a/opendc-integration-jpa/core/build.gradle b/opendc-model-odc/jpa/build.gradle index ed510560..819ef735 100644 --- a/opendc-integration-jpa/core/build.gradle +++ b/opendc-model-odc/jpa/build.gradle @@ -24,7 +24,7 @@ /* Build configuration */ buildscript { - ext.kotlin_version = '1.1.4-3' + ext.kotlin_version = '1.2.10' ext.dokka_version = '0.9.15' repositories { @@ -46,7 +46,6 @@ apply plugin: 'kotlin-jpa' apply plugin: 'org.jetbrains.dokka' apply plugin: 'org.junit.platform.gradle.plugin' - compileKotlin { kotlinOptions { jvmTarget = "1.8" @@ -71,8 +70,8 @@ dokka { } /* Project configuration */ -group 'nl.atlarge.opendc' -version '1.0' +group 'com.atlarge.opendc' +version '1.1' repositories { jcenter() @@ -81,7 +80,7 @@ repositories { dependencies { compile project(':opendc-core') compile project(':opendc-stdlib') - compile project(':opendc-omega') + compile project(':opendc-model-odc:core') compile 'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final' testCompile 'org.junit.jupiter:junit-jupiter-api:5.0.0-RC3' diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaBootstrap.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaBootstrap.kt new file mode 100644 index 00000000..10fc54b5 --- /dev/null +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaBootstrap.kt @@ -0,0 +1,44 @@ +package com.atlarge.opendc.model.odc + +import com.atlarge.opendc.simulator.Bootstrap +import com.atlarge.opendc.model.odc.integration.jpa.schema.Experiment +import com.atlarge.opendc.model.odc.integration.jpa.schema.Task +import com.atlarge.opendc.model.odc.topology.JpaTopologyFactory +import com.atlarge.opendc.model.topology.bootstrap + +/** + * A [Bootstrap] procedure for experiments retrieved from a JPA data store. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +class JpaBootstrap(val experiment: Experiment) : Bootstrap<JpaModel> { + /** + * Bootstrap a model `M` for a kernel in the given context. + * + * @param context The context to bootstrap to model in. + * @return The initialised model for the simulation. + */ + override fun bootstrap(context: Bootstrap.Context<JpaModel>): JpaModel { + val section = experiment.path.sections.first() + + // TODO We should not modify parts of the experiment in a bootstrap as the bootstrap should be reproducible. + // Important: initialise the scheduler of the datacenter + section.datacenter.scheduler = experiment.scheduler + + val topology = JpaTopologyFactory(section) + .create() + .bootstrap() + .bootstrap(context) + val trace = experiment.trace + val tasks = trace.jobs.flatMap { it.tasks } + + // Schedule all messages in the trace + tasks.forEach { task -> + if (task is Task) { + context.schedule(task, section.datacenter, delay = task.startTime) + } + } + + return JpaModel(experiment, topology) + } +} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaModel.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaModel.kt new file mode 100644 index 00000000..6b12a68a --- /dev/null +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaModel.kt @@ -0,0 +1,14 @@ +package com.atlarge.opendc.model.odc + +import com.atlarge.opendc.model.odc.integration.jpa.schema.Experiment +import com.atlarge.opendc.model.topology.MutableTopology + +/** + * Implementation of the [OdcModel] using a JPA backend. + * + * @property experiment The experiment that is simulated. + * @property topology The topology the simulation runs on. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +data class JpaModel(val experiment: Experiment, val topology: MutableTopology): OdcModel, MutableTopology by topology + diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/Jpa.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/Jpa.kt index cbbe280a..4f683f65 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/Jpa.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/Jpa.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa +package com.atlarge.opendc.model.odc.integration.jpa import javax.persistence.EntityManager diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/ParallelizableConverter.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/ParallelizableConverter.kt index 11d5836e..c1123490 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/ParallelizableConverter.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/ParallelizableConverter.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.converter +package com.atlarge.opendc.model.odc.integration.jpa.converter import javax.persistence.AttributeConverter diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/SchedulerConverter.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/SchedulerConverter.kt index 95027440..7c793cba 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/converter/SchedulerConverter.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/SchedulerConverter.kt @@ -22,11 +22,11 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.converter +package com.atlarge.opendc.model.odc.integration.jpa.converter -import nl.atlarge.opendc.platform.scheduler.FifoScheduler -import nl.atlarge.opendc.platform.scheduler.Scheduler -import nl.atlarge.opendc.platform.scheduler.SrtfScheduler +import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler +import com.atlarge.opendc.model.odc.platform.scheduler.FifoScheduler +import com.atlarge.opendc.model.odc.platform.scheduler.SrtfScheduler import javax.persistence.AttributeConverter /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Cpu.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Cpu.kt index b775eb6e..98a51401 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Cpu.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Cpu.kt @@ -22,9 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.topology.machine.Cpu +import com.atlarge.opendc.model.odc.topology.machine.Cpu import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Datacenter.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Datacenter.kt index 1e6eaa2b..8dcc1fc5 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Datacenter.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Datacenter.kt @@ -22,11 +22,11 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.kernel.time.Duration -import nl.atlarge.opendc.platform.scheduler.Scheduler -import nl.atlarge.opendc.topology.container.Datacenter +import com.atlarge.opendc.simulator.Duration +import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler +import com.atlarge.opendc.model.odc.topology.container.Datacenter import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Experiment.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Experiment.kt index 0b352cb4..62a56bab 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Experiment.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Experiment.kt @@ -22,12 +22,10 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.kernel.time.Instant -import nl.atlarge.opendc.platform.Experiment -import nl.atlarge.opendc.platform.scheduler.Scheduler -import nl.atlarge.opendc.platform.workload.Trace +import com.atlarge.opendc.simulator.Instant +import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/ExperimentState.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/ExperimentState.kt index 96fc112c..3e84707f 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/ExperimentState.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/ExperimentState.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema /** * Enumerations of the states an [Experiment] can assume. diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Gpu.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Gpu.kt index 94625242..6b4f77a5 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Gpu.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Gpu.kt @@ -22,9 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.topology.machine.Gpu +import com.atlarge.opendc.model.odc.topology.machine.Gpu import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Job.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Job.kt index 394cf478..192e345c 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Job.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Job.kt @@ -22,11 +22,10 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.platform.workload.Job -import nl.atlarge.opendc.platform.workload.Task -import nl.atlarge.opendc.platform.workload.User +import com.atlarge.opendc.model.odc.platform.workload.Job +import com.atlarge.opendc.model.odc.platform.workload.User import javax.persistence.* /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Machine.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Machine.kt index 4071b342..b1a2e428 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Machine.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Machine.kt @@ -22,9 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.topology.machine.Machine +import com.atlarge.opendc.model.odc.topology.machine.Machine import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/MachineState.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/MachineState.kt index 23efe888..3bd017bc 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/MachineState.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/MachineState.kt @@ -22,9 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.kernel.time.Instant +import com.atlarge.opendc.simulator.Instant import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Path.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Path.kt index ccf3b6e8..f24cf6a0 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Path.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Path.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema import javax.persistence.Entity diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Rack.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Rack.kt index 2d2099a2..571c6e88 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Rack.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Rack.kt @@ -22,9 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.topology.container.Rack +import com.atlarge.opendc.model.odc.topology.container.Rack import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Room.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Room.kt index f3b7ae06..70f326c2 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Room.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Room.kt @@ -22,9 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.topology.container.Room +import com.atlarge.opendc.model.odc.topology.container.Room import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomObject.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomObject.kt index 0e9fb84f..49db076c 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomObject.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomObject.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema import javax.persistence.Entity diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomType.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomType.kt index 5e138947..574677da 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/RoomType.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomType.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema /** * This enumeration defines the room types available in the OpenDC frontend. diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Section.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Section.kt index e3b8c350..79b2d74d 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Section.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Section.kt @@ -22,9 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.kernel.time.Instant +import com.atlarge.opendc.simulator.Instant import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Task.kt index 83a98cfb..9379478f 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Task.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Task.kt @@ -22,11 +22,11 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.kernel.time.Instant -import nl.atlarge.opendc.platform.workload.Task -import nl.atlarge.opendc.platform.workload.TaskState +import com.atlarge.opendc.simulator.Instant +import com.atlarge.opendc.model.odc.platform.workload.Task +import com.atlarge.opendc.model.odc.platform.workload.TaskState import javax.persistence.* /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/TaskState.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/TaskState.kt index 14441752..dab8b345 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/TaskState.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/TaskState.kt @@ -22,9 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.kernel.time.Instant +import com.atlarge.opendc.simulator.Instant import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Trace.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Trace.kt index cd3d9348..eddc1a03 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/integration/jpa/schema/Trace.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Trace.kt @@ -22,10 +22,10 @@ * SOFTWARE. */ -package nl.atlarge.opendc.integration.jpa.schema +package com.atlarge.opendc.model.odc.integration.jpa.schema -import nl.atlarge.opendc.platform.workload.Job -import nl.atlarge.opendc.platform.workload.Trace +import com.atlarge.opendc.model.odc.platform.workload.Job +import com.atlarge.opendc.model.odc.platform.workload.Trace import javax.persistence.Entity /** diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperiment.kt index 9e0e0565..08e89c59 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperiment.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperiment.kt @@ -22,25 +22,25 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform +package com.atlarge.opendc.model.odc.platform import mu.KotlinLogging -import nl.atlarge.opendc.integration.jpa.schema.ExperimentState -import nl.atlarge.opendc.integration.jpa.schema.MachineState -import nl.atlarge.opendc.integration.jpa.transaction -import nl.atlarge.opendc.integration.jpa.schema.Trace as InternalTrace -import nl.atlarge.opendc.integration.jpa.schema.TaskState as InternalTaskState -import nl.atlarge.opendc.integration.jpa.schema.Experiment as InternalExperiment -import nl.atlarge.opendc.integration.jpa.schema.Task as InternalTask -import nl.atlarge.opendc.kernel.Kernel -import nl.atlarge.opendc.kernel.time.Duration -import nl.atlarge.opendc.platform.workload.TaskState -import nl.atlarge.opendc.topology.JpaTopologyFactory -import nl.atlarge.opendc.topology.container.Rack -import nl.atlarge.opendc.topology.container.Room -import nl.atlarge.opendc.topology.destinations -import nl.atlarge.opendc.topology.machine.Machine -import java.util.* +import com.atlarge.opendc.model.odc.integration.jpa.schema.ExperimentState +import com.atlarge.opendc.model.odc.integration.jpa.schema.MachineState +import com.atlarge.opendc.model.odc.integration.jpa.schema.TaskState as InternalTaskState +import com.atlarge.opendc.model.odc.integration.jpa.schema.Trace as InternalTrace +import com.atlarge.opendc.model.odc.integration.jpa.transaction +import com.atlarge.opendc.model.odc.integration.jpa.schema.Experiment as InternalExperiment +import com.atlarge.opendc.model.odc.integration.jpa.schema.Task as InternalTask +import com.atlarge.opendc.simulator.kernel.KernelFactory +import com.atlarge.opendc.simulator.Duration +import com.atlarge.opendc.model.odc.JpaBootstrap +import com.atlarge.opendc.model.odc.platform.workload.TaskState +import com.atlarge.opendc.model.odc.topology.container.Rack +import com.atlarge.opendc.model.odc.topology.container.Room +import com.atlarge.opendc.model.odc.topology.machine.Machine +import com.atlarge.opendc.simulator.platform.Experiment +import com.atlarge.opendc.model.topology.destinations import javax.persistence.EntityManager /** @@ -58,13 +58,13 @@ class JpaExperiment(private val manager: EntityManager, private val logger = KotlinLogging.logger {} /** - * Run the experiment on the specified simulation [Kernel]. + * Run the experiment using the specified simulation kernel implementation. * - * @param kernel The simulation kernel to run the experiment. + * @param factory The simulation kernel implementation to use. * @param timeout The maximum duration of the experiment before returning to the caller. * @return The result of the experiment or `null`. */ - override fun run(kernel: Kernel, timeout: Duration): Unit? { + override fun run(factory: KernelFactory, timeout: Duration): Unit? { if (experiment.state != ExperimentState.CLAIMED) { throw IllegalStateException("The experiment is in illegal state ${experiment.state}") } @@ -74,27 +74,14 @@ class JpaExperiment(private val manager: EntityManager, experiment.state = ExperimentState.SIMULATING } - val section = experiment.path.sections.first() - - // Important: initialise the scheduler of the datacenter - section.datacenter.scheduler = experiment.scheduler + val bootstrap = JpaBootstrap(experiment) + val simulation = factory.create(bootstrap) + val topology = simulation.model - val topology = JpaTopologyFactory(section).create() - val simulation = kernel.create(topology) + val section = experiment.path.sections.first() val trace = experiment.trace val tasks = trace.jobs.flatMap { it.tasks } - logger.info { "Sending trace to kernel ${Objects.hashCode(trace)} ${(trace as InternalTrace).id}" } - - // Schedule all messages in the trace - tasks.forEach { task -> - if (task is InternalTask) { - simulation.schedule(task, section.datacenter, delay = task.startTime) - } else { - logger.warn { "Dropped invalid task $task" } - } - } - // Find all machines in the datacenter val machines = topology.run { section.datacenter.outgoingEdges.destinations<Room>("room").asSequence() @@ -106,20 +93,20 @@ class JpaExperiment(private val manager: EntityManager, while (trace.jobs.any { !it.finished }) { // If we have reached a timeout, return - if (simulation.clock.now >= timeout) + if (simulation.time >= timeout) return null // Collect data of simulation cycle manager.transaction { - experiment.last = simulation.clock.now + experiment.last = simulation.time machines.forEach { machine -> val state = simulation.run { machine.state } val wrapped = MachineState(0, - machine as nl.atlarge.opendc.integration.jpa.schema.Machine, - state.task as nl.atlarge.opendc.integration.jpa.schema.Task?, + machine as com.atlarge.opendc.model.odc.integration.jpa.schema.Machine, + state.task as com.atlarge.opendc.model.odc.integration.jpa.schema.Task?, experiment, - simulation.clock.now, + simulation.time, state.temperature, state.memory, state.load @@ -131,9 +118,9 @@ class JpaExperiment(private val manager: EntityManager, .flatMap { it.tasks.asSequence() } .forEach { task -> val state = InternalTaskState(0, - task as nl.atlarge.opendc.integration.jpa.schema.Task, + task as com.atlarge.opendc.model.odc.integration.jpa.schema.Task, experiment, - simulation.clock.now, + simulation.time, task.remaining.toInt(), 1 ) @@ -142,7 +129,7 @@ class JpaExperiment(private val manager: EntityManager, } // Run next simulation cycle - simulation.run(simulation.clock.now + 1) + simulation.run(simulation.time + 1) } // Set the experiment state @@ -150,7 +137,7 @@ class JpaExperiment(private val manager: EntityManager, experiment.state = ExperimentState.FINISHED } - logger.info { "Simulation done" } + logger.info { "Kernel done" } val waiting: Long = tasks.fold(0.toLong()) { acc, task -> val finished = task.state as TaskState.Finished acc + (finished.previous.at - finished.previous.previous.at) @@ -174,12 +161,12 @@ class JpaExperiment(private val manager: EntityManager, } /** - * Run the experiment on the specified simulation [Kernel]. + * Run the experiment on the specified simulation kernel implementation. * - * @param kernel The simulation kernel to run the experiment. + * @param factory The factory to create the simulation kernel with. * @throws IllegalStateException if the simulation is already running or finished. */ - override fun run(kernel: Kernel) = run(kernel, -1)!! + override fun run(factory: KernelFactory) = run(factory, -1)!! /** * Closes this resource, relinquishing any underlying resources. diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperimentManager.kt index 1d1e118d..698a1129 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaExperimentManager.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperimentManager.kt @@ -22,11 +22,12 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform +package com.atlarge.opendc.model.odc.platform -import nl.atlarge.opendc.integration.jpa.transaction -import nl.atlarge.opendc.integration.jpa.schema.Experiment as InternalExperiment -import nl.atlarge.opendc.integration.jpa.schema.ExperimentState +import com.atlarge.opendc.simulator.platform.Experiment +import com.atlarge.opendc.model.odc.integration.jpa.transaction +import com.atlarge.opendc.model.odc.integration.jpa.schema.Experiment as InternalExperiment +import com.atlarge.opendc.model.odc.integration.jpa.schema.ExperimentState import javax.persistence.EntityManager import javax.persistence.EntityManagerFactory @@ -44,8 +45,7 @@ class JpaExperimentManager(private val factory: EntityManagerFactory): AutoClose private var manager: EntityManager = factory.createEntityManager() /** - * The amount of experiments in the queue. This property makes a call to the database and does therefore not - * run in O(1) time. + * The amount of experiments in the queue. This property is not guaranteed to run in constant time. */ val size: Int get() { diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/topology/JpaTopologyFactory.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/topology/JpaTopologyFactory.kt index 8def721e..3f7c1b8e 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/topology/JpaTopologyFactory.kt +++ b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/topology/JpaTopologyFactory.kt @@ -22,9 +22,17 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.model.odc.topology -import nl.atlarge.opendc.integration.jpa.schema.* +import com.atlarge.opendc.model.odc.integration.jpa.schema.Rack +import com.atlarge.opendc.model.odc.integration.jpa.schema.Room +import com.atlarge.opendc.model.odc.integration.jpa.schema.RoomObject +import com.atlarge.opendc.model.odc.integration.jpa.schema.Section +import com.atlarge.opendc.model.topology.AdjacencyList +import com.atlarge.opendc.model.topology.Topology +import com.atlarge.opendc.model.topology.MutableTopology +import com.atlarge.opendc.model.topology.TopologyBuilder +import com.atlarge.opendc.model.topology.TopologyFactory /** * A [TopologyFactory] that converts a [Section] of an experiment as defined by the API, into a proper [Topology]. diff --git a/opendc-integration-jpa/core/src/main/resources/jpa/schema.xml b/opendc-model-odc/jpa/src/main/resources/jpa/schema.xml index bd6ea7a1..9c5e58bd 100644 --- a/opendc-integration-jpa/core/src/main/resources/jpa/schema.xml +++ b/opendc-model-odc/jpa/src/main/resources/jpa/schema.xml @@ -27,10 +27,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"> - <package>nl.atlarge.opendc.integration.jpa.schema</package> + <package>com.atlarge.opendc.model.odc.integration.jpa.schema</package> <entity class="Experiment" access="FIELD" name="experiments"> - <convert converter="nl.atlarge.opendc.integration.jpa.converter.SchedulerConverter" attribute-name="scheduler" /> + <convert converter="com.atlarge.opendc.model.odc.integration.jpa.converter.SchedulerConverter" attribute-name="scheduler" /> <attributes> <id name="id" /> @@ -51,11 +51,11 @@ <column name="scheduler_name" /> </basic> - <many-to-one name="trace" target-entity="nl.atlarge.opendc.integration.jpa.schema.Trace"> + <many-to-one name="trace" target-entity="com.atlarge.opendc.model.odc.integration.jpa.schema.Trace"> <join-column name="trace_id" /> </many-to-one> - <one-to-one name="path" target-entity="nl.atlarge.opendc.integration.jpa.schema.Path"> + <one-to-one name="path" target-entity="com.atlarge.opendc.model.odc.integration.jpa.schema.Path"> <join-column name="path_id" /> </one-to-one> </attributes> @@ -65,7 +65,7 @@ <attributes> <id name="id" /> - <one-to-many name="sections" target-entity="nl.atlarge.opendc.integration.jpa.schema.Section"> + <one-to-many name="sections" target-entity="com.atlarge.opendc.model.odc.integration.jpa.schema.Section"> <join-column name="path_id" /> </one-to-many> </attributes> @@ -91,7 +91,7 @@ <basic name="name"> <column column-definition="text" /> </basic> - <one-to-many name="jobs" target-entity="nl.atlarge.opendc.integration.jpa.schema.Job"> + <one-to-many name="jobs" target-entity="com.atlarge.opendc.model.odc.integration.jpa.schema.Job"> <join-column name="trace_id" /> </one-to-many> </attributes> @@ -108,7 +108,7 @@ </entity> <entity class="Task" access="FIELD" name="tasks" cacheable="false"> - <convert converter="nl.atlarge.opendc.integration.jpa.converter.ParallelizableConverter" attribute-name="parallelizable" /> + <convert converter="com.atlarge.opendc.model.odc.integration.jpa.converter.ParallelizableConverter" attribute-name="parallelizable" /> <attributes> <id name="id" /> <basic name="flops"> diff --git a/opendc-integration-jpa/mysql/Dockerfile b/opendc-model-odc/setup/Dockerfile index 75e419b4..70e6fe11 100644 --- a/opendc-integration-jpa/mysql/Dockerfile +++ b/opendc-model-odc/setup/Dockerfile @@ -17,7 +17,7 @@ USER root WORKDIR $APP_HOME # Build the application -RUN gradle --no-daemon :opendc-integration-jpa:mysql:installDist +RUN gradle --no-daemon :opendc-model-odc:setup:installDist # Fix permissions RUN chown -R gradle:gradle $APP_HOME @@ -26,5 +26,5 @@ RUN chown -R gradle:gradle $APP_HOME USER gradle # Start the Gradle application on run -CMD opendc-integration-jpa/mysql/build/install/mysql/bin/mysql +CMD opendc-odc-model/setup/build/install/setup/bin/setup diff --git a/opendc-integration-jpa/mysql/build.gradle b/opendc-model-odc/setup/build.gradle index c1cc6f58..042b8f37 100644 --- a/opendc-integration-jpa/mysql/build.gradle +++ b/opendc-model-odc/setup/build.gradle @@ -22,16 +22,65 @@ * SOFTWARE. */ +/* Build configuration */ +buildscript { + ext.kotlin_version = '1.2.10' + ext.dokka_version = '0.9.15' + + repositories { + mavenCentral() + jcenter() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version" + classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version" + } +} + apply plugin: 'java' apply plugin: 'application' -mainClassName = "nl.atlarge.opendc.platform.JpaPlatformRunnerKt" +apply plugin: 'kotlin' +apply plugin: 'org.jetbrains.dokka' + +mainClassName = "nl.atlarge.opendc.model.odc.platform.JpaPlatformRunnerKt" + +compileKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} + +compileTestKotlin { + kotlinOptions { + jvmTarget = "1.8" + } +} + +kotlin { + experimental { + coroutines 'enable' + } +} + +dokka { + outputFormat = 'html' + outputDirectory = "$buildDir/javadoc" +} + +/* Project configuration */ +group 'com.atlarge.opendc' +version '1.1' repositories { jcenter() } dependencies { - compile project(':opendc-integration-jpa:core') + compile project(':opendc-model-odc:jpa') + compile project(':opendc-kernel-omega') + runtime 'org.slf4j:slf4j-simple:1.7.25' runtime 'org.hibernate:hibernate-core:5.2.5.Final' runtime 'mysql:mysql-connector-java:5.1.13' diff --git a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt b/opendc-model-odc/setup/src/main/kotlin/platform/JpaPlatformRunner.kt index 104f1aec..3f0fe589 100644 --- a/opendc-integration-jpa/core/src/main/kotlin/nl/atlarge/opendc/platform/JpaPlatformRunner.kt +++ b/opendc-model-odc/setup/src/main/kotlin/platform/JpaPlatformRunner.kt @@ -22,10 +22,11 @@ * SOFTWARE. */ -package nl.atlarge.opendc.platform +package platform +import com.atlarge.opendc.model.odc.platform.JpaExperimentManager +import com.atlarge.opendc.omega.OmegaKernelFactory import mu.KotlinLogging -import nl.atlarge.opendc.kernel.omega.OmegaKernel import java.util.concurrent.Executors import javax.persistence.Persistence @@ -49,7 +50,7 @@ fun main(args: Array<String>) { val threads = 4 val executorService = Executors.newFixedThreadPool(threads) val experiments = JpaExperimentManager(factory) - val kernel = OmegaKernel + val kernel = OmegaKernelFactory logger.info { "Waiting for enqueued experiments..." } while (true) { diff --git a/opendc-integration-jpa/mysql/src/main/resources/META-INF/persistence.xml b/opendc-model-odc/setup/src/main/resources/META-INF/persistence.xml index 0e40dc6e..0e40dc6e 100644 --- a/opendc-integration-jpa/mysql/src/main/resources/META-INF/persistence.xml +++ b/opendc-model-odc/setup/src/main/resources/META-INF/persistence.xml diff --git a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaSimulation.kt b/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaSimulation.kt deleted file mode 100644 index 48b9d556..00000000 --- a/opendc-omega/src/main/kotlin/nl/atlarge/opendc/kernel/omega/OmegaSimulation.kt +++ /dev/null @@ -1,398 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package nl.atlarge.opendc.kernel.omega - -import mu.KotlinLogging -import nl.atlarge.opendc.kernel.* -import nl.atlarge.opendc.kernel.messaging.Envelope -import nl.atlarge.opendc.kernel.messaging.Receipt -import nl.atlarge.opendc.kernel.time.Clock -import nl.atlarge.opendc.kernel.time.Duration -import nl.atlarge.opendc.kernel.time.Instant -import nl.atlarge.opendc.kernel.time.TickClock -import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.MutableTopology -import nl.atlarge.opendc.topology.Topology -import nl.atlarge.opendc.topology.TopologyContext -import java.util.* -import kotlin.coroutines.experimental.* - -/** - * The Omega simulation kernel is the reference simulation kernel implementation for the OpenDC Simulator core. - * - * This simulator implementation is a single-threaded implementation, running simulation kernels synchronously and - * provides a single priority queue for all events (messages, ticks, etc) that occur in the entities. - * - * By default, [Process]s are resolved as part of the [Topology], meaning each [Entity] in the topology should also - * implement its simulation behaviour by deriving from the [Process] interface. - * - * @property kernel The kernel that facilitates the simulation. - * @property topology The topology to run the simulation over. - * @property clock The clock to use for simulation time. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -internal class OmegaSimulation(override val kernel: OmegaKernel, override val topology: MutableTopology, - override val clock: Clock = TickClock()) : Simulation { - /** - * The logger instance to use for the simulator. - */ - private val logger = KotlinLogging.logger {} - - /** - * The registry of the simulation kernels used in the experiment. - */ - private val registry: MutableMap<Entity<*>, OmegaContext<*, *>> = HashMap() - - /** - * The message queue. - */ - private val queue: Queue<MessageContainer> = PriorityQueue(Comparator.comparingLong(MessageContainer::time)) - - /** - * The context associated with an [Entity]. - */ - @Suppress("UNCHECKED_CAST") - private val <E : Entity<S>, S> E.context: OmegaContext<E, S>? - get() = registry[this] as? OmegaContext<E, S> - - /** - * The observable state of an [Entity] in simulation, which is provided by the simulation context. - */ - override val <E : Entity<S>, S> E.state: S - get() = context?.state ?: initialState - - /** - * Initialise the simulator. - */ - init { - topology.forEach { entity -> - if (entity is Process<*>) { - @Suppress("UNCHECKED_CAST") - val context = registry.computeIfAbsent(entity, { OmegaContext(entity) }) as OmegaContext<Nothing, *> - val process = entity as Process<*> - - // Start all process co-routines - val block: suspend () -> Unit = { process.run { context.run() } } - block.startCoroutine(context) - } - } - } - - /** - * Step through one event in the simulation. - */ - override fun step() { - while (true) { - val envelope = queue.peek() ?: return - val delivery = envelope.time - - if (delivery > clock.now) { - // Tick has yet to occur - // Jump in time to next event - clock.advanceTo(delivery) - break - } else if (delivery < clock.now) { - // Tick has already occurred - logger.warn { "message processed out of order" } - } - // Remove the message from the queue - queue.poll() - - // If the sender has canceled the message, we move on to the next message - if (envelope.canceled) { - continue - } - - val context = envelope.destination.context ?: continue - - if (envelope.message !is Interrupt) { - context.continuation.resume(envelope) - } else { - context.continuation.resumeWithException(envelope.message) - } - - context.last = clock.now - } - } - - /** - * Run a simulation over the specified [Topology]. - * This method will step through multiple cycles in the simulation until no more message exist in the queue. - */ - override fun run() { - while (queue.isNotEmpty()) { - step() - } - } - - /** - * Run a simulation over the specified [Topology], stepping through cycles until (exclusive) the specified clock - * tick has occurred. The control is then handed back to the user. - * - * @param until The point in simulation time at which the simulation should be paused and the control is handed - * back to the user. - */ - override fun run(until: Instant) { - require(until > 0) { "The given instant must be a non-zero positive number" } - - if (clock.now >= until) { - return - } - - while (clock.now < until && queue.isNotEmpty()) { - step() - } - - // Fix clock if step() jumped too far in time to give the impression to the user that simulation stopped at - // exactly the tick it gave. This has not effect on the actual simulation results as the next call to run() will - // just jump forward again. - if (clock.now > until) { - clock.rewindTo(until) - } - } - - /** - * Schedule a message for processing by a [Process]. - * - * @param message The message to schedule. - * @param destination The destination of the message. - * @param sender The sender of the message. - * @param delay The amount of time to wait before processing the message. - */ - override fun schedule(message: Any, destination: Entity<*>, sender: Entity<*>?, delay: Duration): Receipt { - require(delay >= 0) { "The amount of time to delay the message must be a positive number" } - val wrapped = MessageContainer(message, clock.now + delay, sender, destination) - queue.add(wrapped) - return wrapped - } - - /** - * This internal class provides the default implementation for the [Context] interface for this simulator. - */ - private inner class OmegaContext<out E : Entity<S>, S>(override val entity: E) : Context<E>, - Continuation<Unit>, TopologyContext by topology { - /** - * The continuation to resume the execution of the process. - */ - lateinit var continuation: Continuation<Envelope<*>> - - /** - * The last point in time the process has done some work. - */ - var last: Instant = -1 - - /** - * The state of the entity. - */ - var state: S = entity.initialState - - /** - * The [Topology] over which the simulation is run. - */ - override val topology = this@OmegaSimulation.topology - - /** - * The current point in simulation time. - */ - override val time: Instant - get() = clock.now - - /** - * The duration between the current point in simulation time and the last point in simulation time where the - * [Process] has executed some work. - */ - override val delta: Duration - get() = clock.now - last - - /** - * The [CoroutineContext] for a [Process]. - */ - override val context: CoroutineContext = EmptyCoroutineContext - - /** - * The observable state of an [Entity] within the simulation is provided by the context of the simulation. - */ - override val <T : Entity<S>, S> T.state: S - get() = context?.state ?: initialState - - /** - * Retrieve and remove and single message from the mailbox of the [Entity] and suspend the [Process] until the - * message has been received. - * - * @return The envelope containing the message. - */ - suspend fun receiveEnvelope(): Envelope<*> { - return suspendCoroutine { continuation = it } - } - - /** - * Retrieve and removes a single message from the entity's mailbox, suspending the function if the mailbox is empty. - * The execution is resumed after the message has landed in the entity's mailbox after which the message [Envelope] - * is mapped through `block` to generate a processed message. - * - * @param block The block to process the message with. - * @return The processed message. - */ - suspend override fun <T> receive(block: suspend Envelope<*>.(Any) -> T): T { - val envelope = receiveEnvelope() - return block(envelope, envelope.message) - } - - /** - * Retrieve and removes a single message from the entity's mailbox, suspending the function if the mailbox is empty. - * The execution is resumed after the message has landed in the entity's mailbox or the timeout was reached, - * - * If the message has been received, the message [Envelope] is mapped through `block` to generate a processed - * message. If the timeout was reached, `block` is not called and `null` is returned. - * - * @param timeout The duration to wait before resuming execution. - * @param block The block to process the message with. - * @return The processed message or `null` if the timeout was reached. - */ - suspend override fun <T> receive(timeout: Duration, block: suspend Envelope<*>.(Any) -> T): T? { - val receipt = schedule(Timeout, entity, entity, timeout) - val envelope = receiveEnvelope() - - if (envelope.message !is Timeout) { - receipt.cancel() - return block(envelope, envelope.message) - } - - return null - } - - /** - * Send the given message to the specified entity. - * - * @param msg The message to send. - * @param delay The amount of time to wait before the message should be received. - */ - suspend override fun Entity<*>.send(msg: Any, delay: Duration) = send(msg, entity, delay) - - /** - * Send the given message to the specified entity. - * - * @param msg The message to send. - * @param sender The sender of the message. - * @param delay The amount of time to wait before the message should be received. - */ - suspend override fun Entity<*>.send(msg: Any, sender: Entity<*>, delay: Duration): Receipt { - return schedule(msg, this, sender, delay) - } - - /** - * Send an interruption message to the given [Entity]. - */ - suspend override fun Entity<*>.interrupt() { - send(Interrupt) - } - - /** - * Suspend the [Process] of the [Entity] in simulation for one tick in simulation time which is defined by the - * [Clock]. - * - * @return `true` to allow usage in while statements. - */ - suspend override fun tick(): Boolean { - wait(clock.tick) - return true - } - - /** - * Suspend the [Process] of the [Entity] in simulation for the given duration of simulation time before resuming - * execution. - * - * A call to this method will not make the [Process] sleep for the actual duration of time, but instead suspend - * the process until the no more messages at an earlier point in time have to be processed. - * - * @param duration The duration of simulation time to wait before resuming execution. - */ - suspend override fun wait(duration: Duration) { - require(duration >= 0) { "The amount of time to suspend must be a positive number" } - schedule(Resume, entity, entity, duration) - while (true) { - if (receive() is Resume) - return - } - } - - /** - * Suspend the [Process] of the [Entity] in simulation for the given duration of simulation time before resuming - * execution and push all messages that are received during this period to the given queue. - * - * A call to this method will not make the [Process] sleep for the actual duration of time, but instead suspend - * the process until the no more messages at an earlier point in time have to be processed. - * - * @param duration The duration of simulation time to wait before resuming execution. - * @param queue The mutable queue to push the messages to. - */ - suspend override fun wait(duration: Duration, queue: Queue<Any>) { - require(duration >= 0) { "The amount of time to suspend must be a positive number" } - schedule(Resume, entity, entity, duration) - while (true) { - val msg = receive() - if (msg is Resume) - return - queue.add(msg) - } - } - - /** - * Update the state of the entity being simulated. - * - * <p>Instead of directly mutating the entity, we create a new instance of the entity to prevent other objects - * referencing the old entity having their data changed. - * - * @param next The next state of the entity. - */ - suspend override fun <C : Context<E>, E : Entity<S>, S> C.update(next: S) { - @Suppress("UNCHECKED_CAST") - (this as OmegaContext<E, S>).state = next - } - - // Completion continuation implementation - /** - * Resume the execution of this continuation with the given value. - * - * @param value The value to resume with. - */ - override fun resume(value: Unit) { - // Deregister process from registry - registry.remove(entity) - } - - /** - * Resume the execution of this continuation with an exception. - * - * @param exception The exception to resume with. - */ - override fun resumeWithException(exception: Throwable) { - // Deregister process from registry - registry.remove(entity) - - logger.error(exception) { "An exception occurred during the execution of a process" } - } - } -} diff --git a/opendc-stdlib/build.gradle b/opendc-stdlib/build.gradle index a0c92459..ea463f5a 100644 --- a/opendc-stdlib/build.gradle +++ b/opendc-stdlib/build.gradle @@ -24,7 +24,7 @@ /* Build configuration */ buildscript { - ext.kotlin_version = '1.1.4-3' + ext.kotlin_version = '1.2.10' ext.dokka_version = '0.9.15' repositories { @@ -68,8 +68,8 @@ dokka { } /* Project configuration */ -group 'nl.atlarge.opendc' -version '1.0' +group 'com.atlarge.opendc' +version '1.1' repositories { jcenter() diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt index 74b046de..c042a2d5 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt @@ -22,9 +22,10 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.model.topology -import nl.atlarge.opendc.topology.Edge as BaseEdge +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.model.topology.Edge as BaseEdge import java.util.concurrent.atomic.AtomicInteger /** @@ -70,7 +71,7 @@ internal class AdjacencyListTopology : MutableTopology { /** * A mapping of nodes to their internal representation with the edges of the nodes. */ - private var nodes: MutableMap<Entity<*>, Node> = HashMap() + private var nodes: MutableMap<Entity<*, Topology>, Node> = HashMap() // Topology @@ -82,19 +83,19 @@ internal class AdjacencyListTopology : MutableTopology { /** * A unique identifier of this node within the topology. */ - override val Entity<*>.id: Int + override val Entity<*, Topology>.id: Int get() = nodes[this]!!.id /** * The set of ingoing edges of this node. */ - override val Entity<*>.ingoingEdges: MutableSet<BaseEdge<*>> + override val Entity<*, Topology>.ingoingEdges: MutableSet<BaseEdge<*>> get() = nodes[this]!!.ingoingEdges /** * The set of outgoing edges of this node. */ - override val Entity<*>.outgoingEdges: MutableSet<BaseEdge<*>> + override val Entity<*, Topology>.outgoingEdges: MutableSet<BaseEdge<*>> get() = nodes[this]!!.outgoingEdges // MutableTopology @@ -108,7 +109,7 @@ internal class AdjacencyListTopology : MutableTopology { * @param tag The tag of the edge that uniquely identifies the relationship the edge represents. * @return The edge that has been created. */ - override fun <T> connect(from: Entity<*>, to: Entity<*>, label: T, tag: String?): BaseEdge<T> { + override fun <T> connect(from: Entity<*, Topology>, to: Entity<*, Topology>, label: T, tag: String?): BaseEdge<T> { if (!contains(from) || !contains(to)) throw IllegalArgumentException("One of the entities is not part of the topology") val edge = Edge(label, tag, from, to) @@ -125,7 +126,7 @@ internal class AdjacencyListTopology : MutableTopology { * * @return A new [Topology] instance with a copy of the graph. */ - override public fun clone(): Topology { + override fun clone(): Topology { val copy = AdjacencyListTopology() copy.nextId = AtomicInteger(nextId.get()) copy.nodes = HashMap(nodes) @@ -142,12 +143,13 @@ internal class AdjacencyListTopology : MutableTopology { /** * Checks if the specified element is contained in this collection. */ - override fun contains(element: Entity<*>): Boolean = nodes.contains(element) + override fun contains(element: Entity<*, Topology>): Boolean = nodes.contains(element) /** * Checks if all elements in the specified collection are contained in this collection. */ - override fun containsAll(elements: Collection<Entity<*>>): Boolean = elements.all { nodes.containsKey(it) } + override fun containsAll(elements: Collection<Entity<*, Topology>>): Boolean = + elements.all { nodes.containsKey(it) } /** * Returns `true` if the collection is empty (contains no elements), `false` otherwise. @@ -162,7 +164,7 @@ internal class AdjacencyListTopology : MutableTopology { * @param element The element to add to this graph. * @return `true` if the graph has changed, `false` otherwise. */ - override fun add(element: Entity<*>): Boolean { + override fun add(element: Entity<*, Topology>): Boolean { if (nodes.putIfAbsent(element, Node(nextId.getAndIncrement())) == null) { listeners.forEach { it.run { this@AdjacencyListTopology.onNodeAdded(element) } } return true @@ -176,7 +178,7 @@ internal class AdjacencyListTopology : MutableTopology { * @param elements The nodes to add to this graph. * @return `true` if the graph has changed, `false` otherwise. */ - override fun addAll(elements: Collection<Entity<*>>): Boolean = elements.any { add(it) } + override fun addAll(elements: Collection<Entity<*, Topology>>): Boolean = elements.any { add(it) } /** * Remove all nodes and their respective edges from the graph. @@ -189,7 +191,7 @@ internal class AdjacencyListTopology : MutableTopology { * @param element The element to remove from the graph. * @return `true` if the graph has changed, `false` otherwise. */ - override fun remove(element: Entity<*>): Boolean { + override fun remove(element: Entity<*, Topology>): Boolean { nodes[element]?.ingoingEdges?.forEach { it.from.outgoingEdges.remove(it) } @@ -210,7 +212,7 @@ internal class AdjacencyListTopology : MutableTopology { * @param elements The elements to remove from the graph. * @return `true` if the graph has changed, `false` otherwise. */ - override fun removeAll(elements: Collection<Entity<*>>): Boolean = elements.any(this::remove) + override fun removeAll(elements: Collection<Entity<*, Topology>>): Boolean = elements.any(this::remove) /** * Remove all nodes in the graph, except those in the specified collection. @@ -219,7 +221,7 @@ internal class AdjacencyListTopology : MutableTopology { * * @param elements The elements to retain in the graph. */ - override fun retainAll(elements: Collection<Entity<*>>): Boolean { + override fun retainAll(elements: Collection<Entity<*, Topology>>): Boolean { val iterator = nodes.keys.iterator() var changed = false while (iterator.hasNext()) { @@ -238,7 +240,7 @@ internal class AdjacencyListTopology : MutableTopology { * * @return A [MutableIterator] over the nodes of the graph. */ - override fun iterator(): MutableIterator<Entity<*>> = nodes.keys.iterator() + override fun iterator(): MutableIterator<Entity<*, Topology>> = nodes.keys.iterator() /** * The internal representation of a node within the graph. @@ -253,6 +255,6 @@ internal class AdjacencyListTopology : MutableTopology { */ internal class Edge<out T>(override val label: T, override val tag: String?, - override val from: Entity<*>, - override val to: Entity<*>) : BaseEdge<T> + override val from: Entity<*, Topology>, + override val to: Entity<*, Topology>) : BaseEdge<T> } diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt new file mode 100644 index 00000000..de9a41d5 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt @@ -0,0 +1,23 @@ +package com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Bootstrap +import com.atlarge.opendc.simulator.Entity + +/** + * Create a [Bootstrap] procedure for the given [Topology]. + * + * @return A bootstrap procedure for the topology. + */ +fun <T: Topology> T.bootstrap(): Bootstrap<T> = Bootstrap.create { ctx -> + forEach { ctx.register(it) } + listeners += object : TopologyListener { + override fun Topology.onNodeAdded(node: Entity<*, Topology>) { + ctx.register(node) + } + + override fun Topology.onNodeRemoved(node: Entity<*, Topology>) { + ctx.deregister(node) + } + } + this +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Component.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.kt index 3c383892..5e8611a0 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Component.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.model.topology /** * A component within a [Topology], which is either a node or an [Edge] representing the relationship between diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt index 3be14dec..3e507887 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt @@ -22,7 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity /** * An edge that represents a directed relationship between exactly two nodes in a logical topology of a cloud network. @@ -47,7 +49,7 @@ interface Edge<out T> : Component { * This property is not guaranteed to have a runtime complexity of <code>O(1)</code>, but must be at least * <code>O(n)</code>, with respect to the size of the topology. */ - val from: Entity<*> + val from: Entity<*, Topology> /** * The destination of the edge. @@ -55,5 +57,5 @@ interface Edge<out T> : Component { * This property is not guaranteed to have a runtime complexity of <code>O(1)</code>, but must be at least * <code>O(n)</code>, with respect to the size of the topology. */ - val to: Entity<*> + val to: Entity<*, Topology> } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/MutableTopology.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt index 10a55e5b..ac1b4ba5 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/MutableTopology.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt @@ -22,7 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity /** * A subinterface of [Topology] which adds mutation methods. When mutation is not required, users @@ -30,7 +32,7 @@ package nl.atlarge.opendc.topology * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface MutableTopology : Topology, MutableSet<Entity<*>> { +interface MutableTopology : Topology, MutableSet<Entity<*, Topology>> { /** * Create a directed, labeled edge between two nodes in the topology. * @@ -40,7 +42,7 @@ interface MutableTopology : Topology, MutableSet<Entity<*>> { * @param tag The tag of the edge that uniquely identifies the relationship the edge represents. * @return The edge that has been created. */ - fun <T> connect(from: Entity<*>, to: Entity<*>, label: T, tag: String? = null): Edge<T> + fun <T> connect(from: Entity<*, Topology>, to: Entity<*, Topology>, label: T, tag: String? = null): Edge<T> /** * Create a directed, unlabeled edge between two nodes in the topology. @@ -50,7 +52,8 @@ interface MutableTopology : Topology, MutableSet<Entity<*>> { * @param tag The tag of the edge that uniquely identifies the relationship the edge represents. * @return The edge that has been created. */ - fun connect(from: Entity<*>, to: Entity<*>, tag: String? = null): Edge<Unit> = connect(from, to, Unit, tag) + fun connect(from: Entity<*, Topology>, to: Entity<*, Topology>, tag: String? = null): Edge<Unit> = + connect(from, to, Unit, tag) /** * Create a directed, unlabeled edge between two nodes in the topology. @@ -58,5 +61,5 @@ interface MutableTopology : Topology, MutableSet<Entity<*>> { * @param dest The destination of the edge. * @return The edge that has been created. */ - infix fun Entity<*>.to(dest: Entity<*>): Edge<Unit> = connect(this, dest) + infix fun Entity<*, Topology>.to(dest: Entity<*, Topology>): Edge<Unit> = connect(this, dest) } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Topology.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Topology.kt index 27c1c889..1e5a404f 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Topology.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Topology.kt @@ -22,7 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity /** * A graph data structure which represents the logical topology of a cloud network consisting of one or more @@ -32,7 +34,7 @@ package nl.atlarge.opendc.topology * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Topology : TopologyContext, Cloneable, Set<Entity<*>> { +interface Topology : TopologyContext, Cloneable, Set<Entity<*, Topology>> { /** * The listeners of this topology. */ diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyBuilder.kt index bb9c7e8e..44b1cb4e 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyBuilder.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.model.topology /** * A builder for [Topology] instances. diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyContext.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.kt index 22e7dd94..2bf87a39 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyContext.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.kt @@ -22,7 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity /** * A [TopologyContext] represents the context for entities in a specific topology, providing access to the identifier @@ -34,15 +36,15 @@ interface TopologyContext { /** * A unique identifier of an [Entity] within the topology. */ - val Entity<*>.id: Int + val Entity<*, Topology>.id: Int /** * The set of ingoing edges of an [Entity]. */ - val Entity<*>.ingoingEdges: Set<Edge<*>> + val Entity<*, Topology>.ingoingEdges: Set<Edge<*>> /** * The set of outgoing edges of an [Entity]. */ - val Entity<*>.outgoingEdges: Set<Edge<*>> + val Entity<*, Topology>.outgoingEdges: Set<Edge<*>> } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyFactory.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyFactory.kt index 42b30a94..35cfa97a 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyFactory.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyFactory.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.model.topology /** * An interface for producing [Topology] instances. Implementors of this interface provide a way of generating a diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyListener.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt index b5062709..93108cc0 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyListener.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt @@ -22,7 +22,9 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology; +package com.atlarge.opendc.model.topology; + +import com.atlarge.opendc.simulator.Entity /** * A listener interface for [Topology] instances. The methods of this interface are invoked on @@ -36,14 +38,14 @@ interface TopologyListener { * * @param node The entity that has been added to the [Topology]. */ - fun Topology.onNodeAdded(node: Entity<*>) {} + fun Topology.onNodeAdded(node: Entity<*, Topology>) {} /** * This method is invoked when an [Entity] is removed from the [Topology]. * * @param node The entity that has been removed from the [Topology]. */ - fun Topology.onNodeRemoved(node: Entity<*>) {} + fun Topology.onNodeRemoved(node: Entity<*, Topology>) {} /** * This method is invoked when an [Edge] is added to the [Topology]. diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Traversable.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt index e57060ed..23720c46 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Traversable.kt +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package com.atlarge.opendc.model.topology /** * Filter a [Set] of [Edge]s based on the tag of the edges and return the origin nodes casted to type `T`. diff --git a/settings.gradle b/settings.gradle index a92d3d2c..b507653b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -24,7 +24,8 @@ rootProject.name = "opendc-simulator" include 'opendc-core' -include 'opendc-omega' +include 'opendc-kernel-omega' include 'opendc-stdlib' -include 'opendc-integration-jpa:core' -include 'opendc-integration-jpa:mysql' +include 'opendc-model-odc:core' +include 'opendc-model-odc:jpa' +include 'opendc-model-odc:setup' |
