diff options
92 files changed, 612 insertions, 5443 deletions
diff --git a/build.gradle b/build.gradle index 8ce1956a..96031cd8 100644 --- a/build.gradle +++ b/build.gradle @@ -23,23 +23,25 @@ */ plugins { - id 'org.jetbrains.kotlin.jvm' version '1.2.51' apply false - id 'org.jetbrains.kotlin.plugin.jpa' version '1.2.51' apply false + id 'org.jetbrains.kotlin.jvm' version '1.3.0-rc-198' apply false id 'org.jetbrains.dokka' version '0.9.17' apply false } allprojects { group = 'com.atlarge.opendc' - version = '1.2' + version = '2.0.0' ext { - kotlinx_coroutines_version = '0.23.4' - junit_jupiter_version = '5.2.0' - junit_platform_version = '1.2.0' - jacoco_version = '0.8.2-SNAPSHOT' + junit_jupiter_version = '5.3.1' + junit_platform_version = '1.3.1' } } wrapper { - gradleVersion = '4.8' + gradleVersion = '4.10' } + +// Wait for children to evaluate so we can configure tasks that are dependant on children +project.evaluationDependsOnChildren() + +apply from: 'gradle/jacoco.gradle' diff --git a/opendc-model-odc/setup/build.gradle b/gradle/jacoco.gradle index c3976986..687ad093 100644 --- a/opendc-model-odc/setup/build.gradle +++ b/gradle/jacoco.gradle @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,23 +22,34 @@ * SOFTWARE. */ -/* Build configuration */ -apply from: '../../gradle/kotlin.gradle' -apply plugin: 'application' +/* Jacoco task for root project to generate merged report */ +apply plugin: 'jacoco' -mainClassName = "com.atlarge.opendc.model.odc.platform.JpaPlatformRunnerKt" - -/* Project configuration */ repositories { - jcenter() + mavenLocal() + mavenCentral() } -dependencies { - compile project(':opendc-model-odc:jpa') - compile project(':opendc-kernel-omega') - compile "io.github.microutils:kotlin-logging:1.4.6" +task jacocoMerge(type: JacocoMerge, dependsOn: subprojects.test) { + executionData = files(subprojects.jacocoTestReport.executionData) + + doFirst { + executionData = files(executionData.findAll { it.exists() }) + } +} + +task jacocoTestReport(type: JacocoReport, dependsOn: jacocoMerge) { + group = 'Coverage reports' + description = 'Generate an aggregate report from all subprojects' + + executionData tasks.jacocoMerge.destinationFile + subprojects.each { + sourceSets it.sourceSets.main + } - runtimeOnly "org.slf4j:slf4j-simple:1.7.25" - runtimeOnly "org.hibernate:hibernate-core:5.2.5.Final" - runtimeOnly "mysql:mysql-connector-java:5.1.13" + reports { + html.enabled = true + xml.enabled = true + xml.destination file("${buildDir}/reports/jacoco/report.xml") + } } diff --git a/gradle/kotlin.gradle b/gradle/kotlin.gradle index 04f67ae8..7c4495f8 100644 --- a/gradle/kotlin.gradle +++ b/gradle/kotlin.gradle @@ -31,19 +31,13 @@ sourceCompatibility = 1.8 compileKotlin { kotlinOptions { - jvmTarget = "1.8" + jvmTarget = '1.8' } } compileTestKotlin { kotlinOptions { - jvmTarget = "1.8" - } -} - -kotlin { - experimental { - coroutines "enable" + jvmTarget = '1.8' } } @@ -63,20 +57,9 @@ test { } /* Coverage */ -repositories { - // This repository is needed to get the latest snapshot of Jacoco - maven { url = "https://oss.sonatype.org/content/repositories/snapshots" } -} - -jacoco { - // We use the latest snapshot of Jacoco in order to get it to ignore Kotlin-generated code - toolVersion = jacoco_version -} - jacocoTestReport { reports { html.enabled = true - xml.enabled = true } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar Binary files differindex 1948b907..29953ea1 100644 --- a/gradle/wrapper/gradle-wrapper.jar +++ b/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d2c45a4b..115e6ac0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/opendc-core/build.gradle b/odcsim-core/build.gradle index e6c7076b..3ae40a0d 100644 --- a/opendc-core/build.gradle +++ b/odcsim-core/build.gradle @@ -33,9 +33,24 @@ repositories { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib" - api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinx_coroutines_version" testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_jupiter_version" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_jupiter_version" testImplementation "org.junit.platform:junit-platform-launcher:$junit_platform_version" } + +/* Create configuration for test suite used by implementors */ +task testJar(type: Jar, dependsOn: testClasses) { + baseName = "test-${project.archivesBaseName}" + from sourceSets.test.output +} + +configurations { + tests +} + +artifacts { + tests testJar +} + + diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorContext.kt index 1963a056..5a16c4d1 100644 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt +++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorContext.kt @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,40 +22,38 @@ * SOFTWARE. */ -package com.atlarge.opendc.model.topology - -import com.atlarge.opendc.simulator.Entity +package com.atlarge.odcsim /** - * An edge that represents a directed relationship between exactly two nodes in a logical topology of a cloud network. + * Represents the context in which the execution of an actor's behavior takes place. * - * @param T The relationship type the edge represents within a logical topology. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + * @param T The shape of the messages the actor accepts. */ -interface Edge<out T> : Component { +interface ActorContext<in T : Any> { /** - * The label of this edge. + * The identity of the actor, bound to the lifecycle of this actor instance. */ - val label: T + val self: ActorRef<T> /** - * A tag to uniquely identify the relationship this edge represents. + * The point of time within the simulation. */ - val tag: String? + val time: Instant /** - * The source of the edge. + * Spawn a child actor from the given [Behavior] and with the specified name. * - * 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. + * @param name The name of the child actor to spawn. + * @param behavior The behavior of the child actor to spawn. + * @return A reference to the child that has/will be spawned. */ - val from: Entity<*, Topology> + fun <U : Any> spawn(name: String, behavior: Behavior<U>): ActorRef<U> /** - * The destination of the edge. + * Request the specified child actor to be stopped in asynchronous fashion. * - * 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. + * @param child The reference to the child actor to stop. + * @return `true` if the ref points to a child actor, otherwise `false`. */ - val to: Entity<*, Topology> + fun <U : Any> stop(child: ActorRef<U>): Boolean } diff --git a/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorPath.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorPath.kt new file mode 100644 index 00000000..cc3b19af --- /dev/null +++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorPath.kt @@ -0,0 +1,137 @@ +/* + * MIT License + * + * Copyright (c) 2018 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.odcsim + +import java.io.Serializable + +/** + * An actor path represents the unique path to a specific actor instance within an [ActorSystem]. + */ +sealed class ActorPath : Comparable<ActorPath>, Serializable { + /** + * The name of the actor that this path refers to. + */ + abstract val name: String + + /** + * The path for the parent actor. + */ + abstract val parent: ActorPath + + /** + * Walk up the tree to obtain and return the [ActorPath.Root]. + */ + abstract val root: Root + + /** + * Create a new child actor path. + */ + fun child(name: String): ActorPath = Child(this, name) + + /** + * Recursively create a descendant’s path by appending all child names. + */ + fun descendant(children: Iterable<String>): ActorPath = children.fold(this) { parent, name -> + if (name.isNotBlank()) child(name) else parent + } + + /** + * Root of the hierarchy of [ActorPath]s. There is exactly root per [ActorSystem]. + */ + data class Root(override val name: String = "/") : ActorPath() { + init { + require(name.length == 1 || name.indexOf('/', 1) == -1) { + "/ may only exist at the beginning of the root actors name" + } + require(name.indexOf('#') == -1) { "# may not exist in a path component"} + } + + override val parent: ActorPath = this + + override val root: Root = this + + /** + * Compare the [specified][other] path with this root node for order. If both paths are roots, compare their + * name, otherwise the root is ordered higher. + * + * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater + * than the specified path. + */ + override fun compareTo(other: ActorPath): Int = if (other is Root) name.compareTo(other.name) else 1 + + /** + * Create a string representation of this root node which prints its own [name]. + * + * @return A string representation of this node. + */ + override fun toString(): String = name + } + + /** + * A child in the hierarchy of [ActorPath]s. + */ + data class Child(override val parent: ActorPath, override val name: String) : ActorPath() { + init { + require(name.indexOf('/') == -1) { "/ may not exist in a path component" } + require(name.indexOf('#') == -1) { "# may not exist in a path component"} + } + + override val root: Root by lazy { + when (parent) { + is Root -> parent + else -> parent.root + } + } + + /** + * Compare the [specified][other] path with this child node for order. + * + * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater + * than the specified path. + */ + override fun compareTo(other: ActorPath): Int { + tailrec fun rec(left: ActorPath, right: ActorPath): Int = when { + left == right -> 0 + left is Root -> left.compareTo(right) + right is Root -> -(right.compareTo(left)) + else -> { + val x = left.name.compareTo(right.name) + if (x == 0) + rec(left.parent, right.parent) + else + x + } + } + return rec(this, other) + } + + /** + * Create a string representation of this child node which prints the name of [parent] and its own [name]. + * + * @return A string representation of this node. + */ + override fun toString(): String = "$parent/$name" + } +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyBuilder.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorRef.kt index 8bdc37c0..8d1e069c 100644 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyBuilder.kt +++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorRef.kt @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,19 +22,22 @@ * SOFTWARE. */ -package com.atlarge.opendc.model.topology +package com.atlarge.odcsim /** - * A builder for [Topology] instances. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + * A reference to an entity in simulation that accepts messages of type [T]. */ -interface TopologyBuilder : TopologyFactory { +interface ActorRef<in T : Any> { + /** + * The path for this actor (from this actor up to the root actor). + */ + val path: ActorPath + /** - * Construct a [Topology] from the given block and return it. + * Send the specified message to the actor referenced by this [ActorRef]. * - * @param block The block to construct the topology. - * @return The topology that has been built. + * @param msg The message to send to the referenced architecture. + * @param after The delay after which the message should be received by the actor. */ - fun construct(block: MutableTopology.() -> Unit): MutableTopology = create().apply(block) + fun send(msg: T, after: Duration = 0.1) } diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/ExperimentState.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorSystem.kt index dc7355bd..a67f13d9 100644 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/ExperimentState.kt +++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorSystem.kt @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,37 +22,31 @@ * SOFTWARE. */ -package com.atlarge.opendc.model.odc.integration.jpa.schema +package com.atlarge.odcsim /** - * Enumerations of the states an [Experiment] can assume. + * An actor system is a hierarchical grouping of actors that represents a discrete event simulation. * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + * An implementation of this interface should be provided by an engine. See for example *odcsim-engine-omega*, + * which is the reference implementation of the *odcsim* API. + * + * @param T The shape of the messages the root actor in the system can receive. */ -enum class ExperimentState { - /** - * This state indicates the experiment has been queued for simulation, but has not yet started. - */ - QUEUED, - - /** - * This state indicates the experiment has been claimed by a simulator for simulation, but - * not yet started. - */ - CLAIMED, - +interface ActorSystem<in T : Any> : ActorRef<T> { /** - * This state indicates the experiment is currently in simulation. + * The current point in simulation time. */ - SIMULATING, + val time: Instant /** - * This state indicates the experiment has finished simulating. + * The name of this engine instance, used to distinguish between multiple engines running within the same JVM. */ - FINISHED, + val name: String /** - * This states indicates the experiment was aborted due to a timeout. + * Run the actors until the specified point in simulation time. + * + * @param until The point until which the simulation should run. */ - ABORTED, + fun run(until: Duration = Duration.POSITIVE_INFINITY) } diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyFactory.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorSystemFactory.kt index ab2deeb7..f59bc966 100644 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyFactory.kt +++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/ActorSystemFactory.kt @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,19 +22,17 @@ * SOFTWARE. */ -package com.atlarge.opendc.model.topology +package com.atlarge.odcsim /** - * An interface for producing [Topology] instances. Implementors of this interface provide a way of generating a - * topology based on the state of the factory. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + * A factory for [ActorSystem] instances that allows users to dynamically load engine implementations. */ -interface TopologyFactory { +interface ActorSystemFactory { /** - * Create a [MutableTopology] instance. + * Create an [ActorSystem] with the given root [Behavior] and the given name. * - * @return A mutable topology. + * @param root The behavior of the root actor. + * @param name The name of the engine instance. */ - fun create(): MutableTopology + operator fun <T : Any> invoke(root: Behavior<T>, name: String): ActorSystem<T> } diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Job.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/Behavior.kt index 3e6c6821..54b02341 100644 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Job.kt +++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/Behavior.kt @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,32 +22,23 @@ * SOFTWARE. */ -package com.atlarge.opendc.model.odc.platform.workload +package com.atlarge.odcsim /** - * A bag of tasks which are submitted by a [User] to the cloud network. + * The behavior of an actor defines how it reacts to the messages that it receives. + * The message may either be of the type that the actor declares and which is part of the [ActorRef] signature, + * or it may be a system [Signal] that expresses a lifecycle event of either this actor or one of its child actors. * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + * @param T The shape of the messages the behavior accepts. */ -interface Job { +interface Behavior<T : Any> { /** - * A unique identifier of the job. + * Process an incoming message and return the actor's next [Behavior]. */ - val id: Int + fun receive(ctx: ActorContext<T>, msg: T): Behavior<T> = this /** - * The owner of this job. + * Process an incoming [Signal] and return the actor's next [Behavior]. */ - val owner: User - - /** - * The tasks this job consists of. - */ - val tasks: Set<Task> - - /** - * A flag to indicate the job has finished. - */ - val finished: Boolean - get() = !tasks.any { !it.finished } + fun receiveSignal(ctx: ActorContext<T>, signal: Signal): Behavior<T> = this } diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Room.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/Signals.kt index 5e07b0ce..635bf9ac 100644 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Room.kt +++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/Signals.kt @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,14 +22,20 @@ * SOFTWARE. */ -package com.atlarge.opendc.model.odc.topology.container +package com.atlarge.odcsim -import com.atlarge.opendc.model.topology.Topology -import com.atlarge.opendc.simulator.Entity +/** + * System signals are notifications that are generated by the system and delivered to the actor behavior in a reliable + * fashion. + */ +interface Signal /** - * A physical room in a datacenter with relationships to the entities within the room. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + * Lifecycle signal that is fired upon creation of the actor. This will be the first message that the actor receives. + */ +object PreStart : Signal + +/** + * Lifecycle signal that is fired after this actor and all its child actors (transitively) have terminated. */ -interface Room : Entity<Unit, Topology> +object PostStop : Signal diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Time.kt b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/Time.kt index 64e3cb80..8eab3bdc 100644 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Time.kt +++ b/odcsim-core/src/main/kotlin/com/atlarge/odcsim/Time.kt @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,14 +22,14 @@ * SOFTWARE. */ -package com.atlarge.opendc.simulator +package com.atlarge.odcsim /** - * An instantaneous point on the time-line, used to record event time-stamps in a simulation. + * An instantaneous point on the time-line, used to record message time-stamps in a simulation. */ -typealias Instant = Long +typealias Instant = Double /** - * A time interval which represents the amount of elapsed time between two events. + * A time interval which represents the amount of elapsed time between two messages. */ -typealias Duration = Long +typealias Duration = Double diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Trace.kt b/odcsim-core/src/test/kotlin/com/atlarge/odcsim/ActorSystemFactoryTest.kt index 25bcad83..a374548c 100644 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Trace.kt +++ b/odcsim-core/src/test/kotlin/com/atlarge/odcsim/ActorSystemFactoryTest.kt @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,16 +22,14 @@ * SOFTWARE. */ -package com.atlarge.opendc.model.odc.platform.workload +package com.atlarge.odcsim /** - * A timestamped sequence of jobs received in a cloud network. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + * A conformance test suite for implementors of the [ActorSystemFactory] interface. */ -interface Trace { +abstract class ActorSystemFactoryTest { /** - * The [Job]s in the trace. + * Create an [ActorSystemFactory] instance to test. */ - val jobs: Set<Job> + abstract fun createFactory(): ActorSystemFactory } diff --git a/odcsim-core/src/test/kotlin/com/atlarge/odcsim/ActorSystemTest.kt b/odcsim-core/src/test/kotlin/com/atlarge/odcsim/ActorSystemTest.kt new file mode 100644 index 00000000..62df356b --- /dev/null +++ b/odcsim-core/src/test/kotlin/com/atlarge/odcsim/ActorSystemTest.kt @@ -0,0 +1,101 @@ +/* + * MIT License + * + * Copyright (c) 2018 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.odcsim + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Assumptions.assumeTrue +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import java.lang.IllegalArgumentException + +const val DELTA: Double = 0.0001 + +/** + * A conformance test suite for implementors of the [ActorSystem] interface. + */ +abstract class ActorSystemTest { + /** + * An [ActorSystemFactory] provided by implementors to create the [ActorSystem] to be tested. + */ + abstract val factory: ActorSystemFactory + + /** + * Test whether the created [ActorSystem] has the correct name. + */ + @Test + fun `should have a name`() { + val name = "test" + val system = factory(object : Behavior<Unit> {}, name) + + assertEquals(name, system.name) + } + + /** + * Test whether creating an [ActorSystem] sets the initial time at 0. + */ + @Test + fun `should start at t=0`() { + val system = factory(object : Behavior<Unit> {}, name = "test") + + assertTrue(Math.abs(system.time) < DELTA) + } + + /** + * Test whether an [ActorSystem] does not accept invalid points in time. + */ + @Test + fun `should not accept negative instants for running`() { + val system = factory(object : Behavior<Unit> {}, name = "test") + assertThrows<IllegalArgumentException> { system.run(-10.0) } + } + + /** + * Test whether an [ActorSystem] will not jump backward in time when asking to run until a specified instant + * that has already occurred. + */ + @Test + fun `should not jump backward in time`() { + val until = 10.0 + val system = factory(object : Behavior<Unit> {}, name = "test") + + system.run(until = until) + system.run(until = until - 0.5) + assertTrue(Math.abs(system.time - until) < DELTA) + } + + /** + * Test whether an [ActorSystem] will jump forward in time when asking to run until a specified instant. + */ + @Test + fun `should jump forward in time`() { + val until = 10.0 + val system = factory(object : Behavior<Unit> {}, name = "test") + + assumeTrue(Math.abs(system.time) < DELTA) + system.run(until = until) + assertTrue(Math.abs(system.time - until) < DELTA) + } +} diff --git a/opendc-kernel-omega/build.gradle b/odcsim-engine-omega/build.gradle index 9170e73d..4f01e4ca 100644 --- a/opendc-kernel-omega/build.gradle +++ b/odcsim-engine-omega/build.gradle @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -32,11 +32,12 @@ repositories { } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib" + api project(':odcsim-core') - api project(':opendc-core') + implementation "org.jetbrains.kotlin:kotlin-stdlib" implementation "io.github.microutils:kotlin-logging:1.4.6" + testCompile project(path: ':odcsim-core', configuration: 'tests') testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_jupiter_version" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_jupiter_version" testImplementation "org.junit.platform:junit-platform-launcher:$junit_platform_version" diff --git a/odcsim-engine-omega/src/main/kotlin/com/atlarge/odcsim/engine/omega/OmegaActorSystem.kt b/odcsim-engine-omega/src/main/kotlin/com/atlarge/odcsim/engine/omega/OmegaActorSystem.kt new file mode 100644 index 00000000..ffc68d0b --- /dev/null +++ b/odcsim-engine-omega/src/main/kotlin/com/atlarge/odcsim/engine/omega/OmegaActorSystem.kt @@ -0,0 +1,186 @@ +/* + * MIT License + * + * Copyright (c) 2018 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.odcsim.engine.omega + +import com.atlarge.odcsim.ActorContext +import com.atlarge.odcsim.ActorPath +import com.atlarge.odcsim.ActorRef +import com.atlarge.odcsim.ActorSystem +import com.atlarge.odcsim.Behavior +import com.atlarge.odcsim.Duration +import com.atlarge.odcsim.Instant +import com.atlarge.odcsim.PostStop +import com.atlarge.odcsim.PreStart +import com.atlarge.odcsim.Signal +import mu.KotlinLogging +import java.util.PriorityQueue +import kotlin.math.max + +/** + * The reference implementation of the [ActorSystem] instance for the OpenDC simulation core. + * + * This engine implementation is a single-threaded implementation, running actors synchronously and + * provides a single priority queue for all events (messages, ticks, etc) that occur. + * + * @param root The behavior of the root actor. + * @param name The name of the engine instance. + */ +class OmegaActorSystem<in T : Any>(root: Behavior<T>, override val name: String) : ActorSystem<T>, ActorRef<T> { + /** + * The current point in simulation time. + */ + override var time: Instant = .0 + + /** + * The path to the root actor. + */ + override val path: ActorPath = ActorPath.Root() + + /** + * The event queue to process + */ + private val queue: PriorityQueue<Envelope> = PriorityQueue(Comparator + .comparingDouble(Envelope::time) + .thenComparingLong(Envelope::id)) + + /** + * The registry of actors in the system. + */ + private val registry: MutableMap<ActorPath, Actor<*>> = HashMap() + + private val logger = KotlinLogging.logger {} + + override fun run(until: Duration) { + require(until >= .0) { "The given instant must be a positive number" } + + while (true) { + val envelope = queue.peek() ?: break + val delivery = envelope.time.takeUnless { it > until } ?: break + + if (delivery < time) { + // Message out of order + logger.warn { "Message delivered out of order [expected=$delivery, actual=$time]" } + } + + time = delivery + queue.poll() + + // Notice that messages for unknown/terminated actors are ignored for now + registry[envelope.destination]?.interpretMessage(envelope.message) + } + + // Jump forward in time as the caller expects the system to have run until the specified instant + // Taking the maximum value prevents the caller to jump backwards in time + time = max(time, until) + } + + override fun send(msg: T, after: Duration) = schedule(this, msg, after) + + /** + * The identifier for the next message to be scheduled. + */ + private var nextId: Long = 0 + + init { + registry[path] = Actor(this, root) + schedule(this, PreStart, .0) + } + + private inner class Actor<T : Any>(override val self: ActorRef<T>, var behavior: Behavior<T>) : ActorContext<T> { + val children: MutableSet<Actor<*>> = mutableSetOf() + + override val time: Instant + get() = this@OmegaActorSystem.time + + override fun <U : Any> spawn(name: String, behavior: Behavior<U>): ActorRef<U> { + val ref = ActorRefImpl<U>(self.path.child(name)) + if (ref.path !in registry) { + val actor = Actor(ref, behavior) + registry[ref.path] = actor + children += actor + schedule(ref, PreStart, .0) + } + return ref + } + + override fun <U : Any> stop(child: ActorRef<U>): Boolean { + if (child.path.root != this@OmegaActorSystem.path) { + // This child is not part of the hierarchy. + return false + } + val ref = registry[child.path] ?: return false + ref.terminate() + return true + } + + /** + * Terminate this actor and its children. + */ + fun terminate() { + children.forEach { it.terminate() } + registry.remove(self.path) + interpretMessage(PostStop) + } + + /** + * Interpret the given message send to an actor. Make sure the message is of the correct type. + */ + fun interpretMessage(msg: Any) { + @Suppress("UNCHECKED_CAST") + behavior = if (msg is Signal) behavior.receiveSignal(this, msg) else behavior.receive(this, msg as T) + } + + override fun equals(other: Any?): Boolean = + other is OmegaActorSystem<*>.Actor<*> && self.path == other.self.path + + override fun hashCode(): Int = self.path.hashCode() + } + + private inner class ActorRefImpl<T : Any>(override val path: ActorPath) : ActorRef<T> { + override fun send(msg: T, after: Duration) = schedule(this, msg, after) + } + + /** + * A wrapper around a message that has been scheduled for processing. + * + * @property time The point in time to deliver the message. + * @property id The identifier of the message to keep the priority queue stable. + * @property destination The destination of the message. + * @property message The message to wrap. + */ + private class Envelope(val time: Instant, val id: Long, val destination: ActorPath, val message: Any) + + /** + * Schedule a message to be processed by the engine. + * + * @property destination The destination of the message. + * @param message The message to schedule. + * @param delay The time to wait before processing the message. + */ + private fun schedule(destination: ActorRef<*>, message: Any, delay: Duration) { + require(delay >= .0) { "The given delay must be a non-negative number" } + queue.add(Envelope(time + delay, nextId++, destination.path, message)) + } +} diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/User.kt b/odcsim-engine-omega/src/main/kotlin/com/atlarge/odcsim/engine/omega/OmegaActorSystemFactory.kt index da696d88..84bf1efb 100644 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/User.kt +++ b/odcsim-engine-omega/src/main/kotlin/com/atlarge/odcsim/engine/omega/OmegaActorSystemFactory.kt @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,24 +22,17 @@ * SOFTWARE. */ -package com.atlarge.opendc.model.odc.platform.workload +package com.atlarge.odcsim.engine.omega + +import com.atlarge.odcsim.ActorSystem +import com.atlarge.odcsim.ActorSystemFactory +import com.atlarge.odcsim.Behavior +import java.util.ServiceLoader /** - * A user of a cloud network that provides [Job]s for the simulation. - * - * Each user in a simulation has its own logical view of the cloud network which is used to route its jobs in the - * physical network. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + * An [ActorSystemFactory] for the Omega engine, used by the [ServiceLoader] API to create [OmegaActorSystem] instances. */ -interface User { - /** - * The unique identifier of the user. - */ - val id: Int - - /** - * The name of this user. - */ - val name: String +class OmegaActorSystemFactory : ActorSystemFactory { + override operator fun <T : Any> invoke(root: Behavior<T>, name: String): ActorSystem<T> = + OmegaActorSystem(root, name) } diff --git a/odcsim-engine-omega/src/main/resources/META-INF/services/com.atlarge.odcsim.ActorSystemFactory b/odcsim-engine-omega/src/main/resources/META-INF/services/com.atlarge.odcsim.ActorSystemFactory new file mode 100644 index 00000000..d0ca8859 --- /dev/null +++ b/odcsim-engine-omega/src/main/resources/META-INF/services/com.atlarge.odcsim.ActorSystemFactory @@ -0,0 +1 @@ +com.atlarge.odcsim.engine.omega.OmegaActorSystemFactory diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Topology.kt b/odcsim-engine-omega/src/test/kotlin/com/atlarge/odcsim/SmokeTest.kt index e277bc9f..a543d9d1 100644 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Topology.kt +++ b/odcsim-engine-omega/src/test/kotlin/com/atlarge/odcsim/SmokeTest.kt @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2017 atlarge-research + * Copyright (c) 2018 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 @@ -22,29 +22,30 @@ * SOFTWARE. */ -package com.atlarge.opendc.model.topology +package com.atlarge.odcsim -import com.atlarge.opendc.simulator.Entity +import com.atlarge.odcsim.engine.omega.OmegaActorSystem +import org.junit.jupiter.api.Test /** - * A graph data structure which represents the logical topology of a cloud network consisting of one or more - * datacenters. - * - * A topology is [Iterable] and allows implementation-dependent iteration of the nodes in the topology. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + * A test to verify the system runs without smoking. */ -interface Topology : TopologyContext, Cloneable, Set<Entity<*, Topology>> { - /** - * The listeners of this topology. - */ - val listeners: MutableSet<TopologyListener> +class SmokeTest { + @Test + fun `hello-world`() { + val system = OmegaActorSystem(object : Behavior<String> { + override fun receive(ctx: ActorContext<String>, msg: String): Behavior<String> { + println("${ctx.time} $msg") + return this + } - /** - * Create a copy of the topology. - * - * @return A new [Topology] with a copy of the graph. - */ - public override fun clone(): Topology -} + override fun receiveSignal(ctx: ActorContext<String>, signal: Signal): Behavior<String> { + println("${ctx.time} $signal") + return this + } + }, name = "test") + system.send("Hello World", after = 1.2) + system.run() + } +} 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 deleted file mode 100644 index 5f41c727..00000000 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Bootstrap.kt +++ /dev/null @@ -1,64 +0,0 @@ -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> { - /** - * Apply the apply procedure for model `M` for a simulation in the given context. - * - * @param context The context to apply to model in. - * @return The initialised, resulting model for the simulation. - */ - fun apply(context: Context<M>): M - - /** - * A context for the apply 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 to be received by the given [Entity]. - * - * @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 apply for a model of type `M`. - * - * @param block The block to produce the apply. - * @return The apply procedure that has been built. - */ - fun <M> create(block: (Context<M>) -> M): Bootstrap<M> = object : Bootstrap<M> { - override fun apply(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 deleted file mode 100644 index 23d10e8f..00000000 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Context.kt +++ /dev/null @@ -1,168 +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 com.atlarge.opendc.simulator - -import java.util.* -import kotlin.coroutines.experimental.CoroutineContext - -/** - * 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, M> : CoroutineContext.Element { - /** - * 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 [Entity] associated with this context. - */ - val self: Entity<S, M> - - /** - * The sender of the last received message or `null` in case the process has not received any messages yet. - * - * Note that this property is only guaranteed to be correct when accessing after a single suspending call. Methods - * like `hold()` and `interrupt()` may change the value of this property. - */ - val sender: Entity<*, *>? - - /** - * 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. - * - * @param interrupt The interrupt to throw at the entity. - */ - suspend fun Entity<*, *>.interrupt(interrupt: Interrupt) - - /** - * Interrupt an [Entity] process in simulation. - * - * @see [Entity.interrupt(Interrupt)] - * @param reason The reason for interrupting the entity. - */ - suspend fun Entity<*, *>.interrupt(reason: String) = interrupt(Interrupt(reason)) - - /** - * 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 and returned. - * - * @return The received message. - */ - suspend fun receive(): Any - - /** - * 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? - - /** - * 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) - - /** - * 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(msg, self, delay) - - /** - * This key provides users access to an untyped process context in case the coroutine runs inside a simulation. - */ - companion object Key : CoroutineContext.Key<Context<*, *>> -} - -/** - * An [Interrupt] message is sent to an [Entity] process in order to interrupt its suspended state. - * - * @param reason The reason for the interruption of the process. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -open class Interrupt(reason: String) : Throwable(reason) diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Entity.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Entity.kt deleted file mode 100644 index 56704c5d..00000000 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Entity.kt +++ /dev/null @@ -1,44 +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 com.atlarge.opendc.simulator - -/** - * An entity in some model `M`. - * - * <p>A [Entity] directly contains its immutable properties that remain unchanged during simulation. - * - * <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, in M> { - /** - * The initial state of the entity. - */ - val initialState: S -} 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 deleted file mode 100644 index f2b8a52b..00000000 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Process.kt +++ /dev/null @@ -1,27 +0,0 @@ -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, 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/com/atlarge/opendc/simulator/instrumentation/Instrument.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Instrument.kt deleted file mode 100644 index 7633444e..00000000 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Instrument.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.atlarge.opendc.simulator.instrumentation - -import com.atlarge.opendc.simulator.Context -import com.atlarge.opendc.simulator.Entity -import kotlinx.coroutines.experimental.channels.ReceiveChannel -import kotlinx.coroutines.experimental.channels.SendChannel - - /** - * A kernel instrumentation device that allows the observation and measurement of properties of interest within some - * model. - * - * An instrument is a [Process] that emits measurements from within some model in the form of a typed stream. An - * instrument is attached to a simulation using the [Port.install] method, which returns a [ReceiveChannel] from - * which the measurements can be extracted out of the simulation. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -typealias Instrument<T, M> = suspend InstrumentScope<T, M>.() -> Unit - -/** - * This interface defines the scope in which an instrumentation device is built. - * - * An instrument is a [Process] without any observable state that is allowed to send messages to other [Entity] - * instances in the simulation. In addition, the instrument can emit measurements using the methods provided by the - * [SendChannel] interface. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface InstrumentScope<in T, M>: SendChannel<T>, Context<Unit, M> diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Port.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Port.kt deleted file mode 100644 index 880f9a15..00000000 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Port.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.atlarge.opendc.simulator.instrumentation - -import com.atlarge.opendc.simulator.kernel.Simulation -import kotlinx.coroutines.experimental.channels.Channel -import kotlinx.coroutines.experimental.channels.ReceiveChannel - -/** - * A port allows users to install instrumentation devices to a [Simulation]. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Port<M> { - /** - * Install the given instrumentation device to produce a stream of measurements of type <code>T</code>. - * - * The [ReceiveChannel] returned by this channel is by default backed by an unlimited buffer - * (using [Channel.UNLIMITED]), which may induce unnecessary overhead. - * - * @param instrument The instrumentation device to install. - * @return A [ReceiveChannel] to which the of measurements produced by the instrument are published. - */ - fun <T> install(instrument: Instrument<T, M>): ReceiveChannel<T> = install(Channel.UNLIMITED, instrument) - - /** - * Install the given instrumentation device to produce a stream of measurements of type code>T</code>. - * - * @param capacity The capacity of the buffer of the channel. - * @param instrument The instrumentation device to install. - * @return A [ReceiveChannel] to which the of measurements produced by the instrument are published. - */ - fun <T> install(capacity: Int, instrument: Instrument<T, M>): ReceiveChannel<T> - - /** - * Close this port and stop the instruments from producing more measurements. - * This is an idempotent operation – repeated invocations of this function have no effect and return false. - * - * @param cause An optional cause that is thrown when trying to receive more elements from the installed - * instruments. - * @return `true` if the port was closed, `false` if it was already closed. - */ - fun close(cause: Throwable? = null): Boolean -} diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/Kernel.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/Kernel.kt deleted file mode 100644 index d4995283..00000000 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/Kernel.kt +++ /dev/null @@ -1,43 +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 com.atlarge.opendc.simulator.kernel - -import com.atlarge.opendc.simulator.Bootstrap - -/** - * A message-based discrete event simulator (DES). This interface is a factory for creating [Simulation]s using the - * provided [Bootstrap] for the model. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Kernel { - /** - * Create a simulation over the given model facilitated by this simulation kernel. - * - * @param bootstrap The apply procedure to apply the simulation with. - * @return A [Simulation] instance representing the simulation. - */ - fun <M> create(bootstrap: Bootstrap<M>): Simulation<M> -} diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/Simulation.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/Simulation.kt deleted file mode 100644 index 14ce5a1a..00000000 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/kernel/Simulation.kt +++ /dev/null @@ -1,89 +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 com.atlarge.opendc.simulator.kernel - -import com.atlarge.opendc.simulator.Entity -import com.atlarge.opendc.simulator.Instant -import com.atlarge.opendc.simulator.instrumentation.Instrument -import com.atlarge.opendc.simulator.instrumentation.Port - -/** - * A message based discrete event simulation over some model `M`. This interface provides direct control over the - * simulation, allowing the user to step over cycles of the simulation and inspecting the state of the simulation via - * [Entity.state]. - * - * @param M The shape of the model over which the simulation runs. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Simulation<M> { - /** - * The model in which the simulation runs. - */ - val model: M - - /** - * The simulation time. - */ - 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 - - /** - * Open a new [Port] to manage [Instrument]s. - * - * @return A new [Port] instance to install [Instrument]s to. - */ - fun openPort(): Port<M> - - /** - * Step through one cycle in the simulation. This method will process all events in a single tick, update the - * internal clock and then return the control to the user. - * - * This method will throw if a process running during the cycle throws an exception. - */ - fun step() - - /** - * 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. - * - * This method will throw if a process running during a cycle throws an exception. - */ - fun run() - - /** - * 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. - * - * This method will throw if a process running during a cycle throws an exception. - * - * @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) -} diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/platform/Experiment.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/platform/Experiment.kt deleted file mode 100644 index eb959ded..00000000 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/platform/Experiment.kt +++ /dev/null @@ -1,52 +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 com.atlarge.opendc.simulator.platform - -import com.atlarge.opendc.simulator.Duration -import com.atlarge.opendc.simulator.kernel.Kernel - -/** - * A blueprint for a reproducible simulation in a pre-defined setting. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Experiment<out T> { - /** - * Run the experiment on the specified kernel implementation. - * - * @param factory The factory to create the simulation kernel with. - * @return The result of the experiment. - */ - fun run(factory: Kernel): T - - /** - * Run the experiment on the specified kernel implementation. - * - * @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(factory: Kernel, timeout: Duration): T? -} diff --git a/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/Messages.kt b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/Messages.kt deleted file mode 100644 index d63a53c8..00000000 --- a/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/Messages.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.atlarge.opendc.omega - -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 - * and resume execution. - * - * This message is not guaranteed to work on other simulation kernels and [Context.interrupt] should be preferred to - * wake up a process from another entity. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -object Resume - -/** - * An internal message used by the Omega simulation kernel to indicate to a suspended [Process], that a timeout has been - * reached and that it should wake up and resume execution. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -object Timeout - -/** - * An internal message used by the Omega simulation kernel to launch a process. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -data class Launch<M>(val process: Process<*, M>) 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 deleted file mode 100644 index c0ab9fb4..00000000 --- a/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaKernel.kt +++ /dev/null @@ -1,47 +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 com.atlarge.opendc.omega - -import com.atlarge.opendc.simulator.Bootstrap -import com.atlarge.opendc.simulator.kernel.Kernel -import com.atlarge.opendc.simulator.kernel.Simulation - -/** - * 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. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -object OmegaKernel : Kernel { - /** - * Create a simulation over the given model facilitated by this simulation kernel. - * - * @param bootstrap The apply procedure to apply the simulation with. - * @return A [Simulation] instance to control the simulation. - */ - override fun <M> create(bootstrap: Bootstrap<M>): Simulation<M> = OmegaSimulation(bootstrap) -} diff --git a/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaSimulation.kt b/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaSimulation.kt deleted file mode 100644 index 03861864..00000000 --- a/opendc-kernel-omega/src/main/kotlin/com/atlarge/opendc/omega/OmegaSimulation.kt +++ /dev/null @@ -1,435 +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 com.atlarge.opendc.omega - -import com.atlarge.opendc.simulator.* -import com.atlarge.opendc.simulator.instrumentation.Instrument -import com.atlarge.opendc.simulator.instrumentation.InstrumentScope -import com.atlarge.opendc.simulator.instrumentation.Port -import com.atlarge.opendc.simulator.kernel.Simulation -import kotlinx.coroutines.experimental.channels.Channel -import kotlinx.coroutines.experimental.channels.ReceiveChannel -import kotlinx.coroutines.experimental.channels.SendChannel -import mu.KotlinLogging -import java.lang.ref.WeakReference -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 OmegaSimulation<M>(bootstrap: Bootstrap<M>) : Simulation<M>, Bootstrap.Context<M> { - /** - * The logger instance to use for the simulator. - */ - private val logger = KotlinLogging.logger {} - - /** - * The registry of the processes used in the simulation. - */ - private val registry: MutableMap<Entity<*, *>, OmegaContext<*>> = HashMap() - - /** - * The message queue. - */ - private val queue: Queue<Envelope> = PriorityQueue(Comparator - .comparingLong(Envelope::time) - .thenComparingLong(Envelope::id)) - - /** - * The kernel process instance that handles internal operations during the simulation. - */ - private val process = object : Process<Unit, M> { - override val initialState = Unit - - override suspend fun Context<Unit, M>.run() { - while(true) { - val msg = receive() - when (msg) { - is Launch<*> -> - @Suppress("UNCHECKED_CAST") - launch((msg as Launch<M>).process) - } - } - } - } - - /** - * 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> - - /** - * The simulation time. - */ - override var time: Instant = 0 - - /** - * The model of simulation. - */ - // XXX: the bootstrap requires the properties of this class to be initialised, so changing the order may cause NPEs - override var model: M = bootstrap.apply(this) - - /** - * 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 simulation instance. - */ - init { - // Launch the Omega kernel process - launch(process) - } - - // Bootstrap Context implementation - override fun register(entity: Entity<*, M>): Boolean { - if (!registry.containsKey(entity) && entity !is Process) { - return false - } - - schedule(Launch(entity as Process<*, M>), process) - 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)) - - // Simulation implementation - override fun openPort(): Port<M> = object : Port<M> { - val channels: MutableSet<WeakReference<Channel<*>>> = mutableSetOf() - - override fun <T> install(capacity: Int, instrument: Instrument<T, M>): ReceiveChannel<T> { - val channel = Channel<T>(capacity) - val process = object : Process<Unit, M> { - override val initialState = Unit - override suspend fun Context<Unit, M>.run() { - val builder = object : InstrumentScope<T, M>, SendChannel<T> by channel, Context<Unit, M> by this {} - try { - instrument(builder) - channel.close() - } catch (cause: Throwable) { - channel.close(cause) - } - } - } - channels.add(WeakReference(channel)) - register(process) - return channel - } - - override fun close(cause: Throwable?): Boolean = channels - .map { it.get()?.close(cause) ?: false } - .any() - } - - 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 - val continuation = context.continuation ?: continue - - // Clear the continuation to prevent resuming an already resumed continuation - context.continuation = null - - if (envelope.message is Interrupt) { - continuation.resumeWithException(envelope.message) - } else { - continuation.resume(envelope) - } - - 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 - } - } - - /** - * The identifier for the next message to be scheduled. - */ - private var nextId: Long = 0 - - /** - * A wrapper around a message that has been scheduled for processing. - * - * @property id The identifier of the message to keep the priority queue stable - * @property message The message to wrap. - * @property time The point in time to deliver the message. - * @property sender The sender of the message. - * @property destination The destination of the message. - */ - private data class Envelope(val id: Long, - val message: Any, - val time: Instant, - val sender: Entity<*, *>?, - val destination: Entity<*, *>) { - /** - * A flag to indicate the message has been canceled. - */ - internal var canceled: Boolean = false - } - - /** - * Schedule the given envelope to be processed by the kernel. - * - * @param envelope The envelope containing the message to schedule. - */ - private fun schedule(envelope: Envelope) { - queue.add(envelope) - } - - /** - * Prepare a message for scheduling by wrapping it into an envelope. - * - * @param message The message to send. - * @param destination The destination entity that should receive the message. - * @param sender The optional sender of the message. - * @param delay The time to delay the message. - */ - private fun prepare(message: Any, destination: Entity<*, *>, sender: Entity<*, *>? = null, - delay: Duration): Envelope { - require(delay >= 0) { "The amount of time to delay the message must be a positive number" } - return Envelope(nextId++, message, time + delay, sender, destination) - } - - /** - * Launch the given [Process]. - * - * @param process The process to launch. - */ - private fun launch(process: Process<*, M>) { - val context = OmegaContext(process).also { registry[process] = it } - - // Bootstrap the process coroutine - val block: suspend () -> Unit = { context.start() } - block.startCoroutine(context) - } - - /** - * 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>, - AbstractCoroutineContextElement(Context) { - /** - * The model in which the process exists. - */ - override val model: M - get() = this@OmegaSimulation.model - - /** - * The current point in simulation time. - */ - override val time: Instant - get() = this@OmegaSimulation.time - - /** - * The [Entity] associated with this context. - */ - override val self: Entity<S, M> - get() = process - - /** - * 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 state of the entity. - */ - override var state: S = process.initialState - - /** - * 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 - - /** - * The sender of the last received message or `null` in case the process has not received any messages yet. - */ - override var sender: Entity<*, *>? = null - - /** - * The [CoroutineContext] for a [Context]. - */ - override val context: CoroutineContext = this - - /** - * The continuation to resume the execution of the process. - */ - var continuation: Continuation<Envelope>? = null - - /** - * The last point in time the process has done some work. - */ - var last: Instant = -1 - - override suspend fun receive(): Any = receiveEnvelope().message - - override suspend fun receive(timeout: Duration): Any? { - val send = prepare(Timeout, process, process, timeout).also { schedule(it) } - - try { - val received = receiveEnvelope() - - if (received.message != Timeout) { - send.canceled = true - return received.message - } - - return null - } finally { - send.canceled = true - } - } - - override suspend fun Entity<*, *>.send(msg: Any, sender: Entity<*, *>, delay: Duration) = - schedule(prepare(msg, this, sender, delay)) - - override suspend fun Entity<*, *>.interrupt(interrupt: Interrupt) = send(interrupt) - - override suspend 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() == Resume) - return - } - } finally { - envelope.canceled = true - } - } - - override suspend 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 == Resume) - return - queue.add(msg) - } - } finally { - envelope.canceled = true - } - } - - /** - * Start the process associated with this context. - */ - internal suspend fun start() = process.run { run() } - - /** - * 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() = suspendCoroutine<Envelope> { continuation = it } - .also { sender = it.sender } - - // 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) = throw exception - } -} diff --git a/opendc-kernel-omega/src/test/kotlin/com/atlarge/opendc/omega/ProcessTest.kt b/opendc-kernel-omega/src/test/kotlin/com/atlarge/opendc/omega/ProcessTest.kt deleted file mode 100644 index 334dca41..00000000 --- a/opendc-kernel-omega/src/test/kotlin/com/atlarge/opendc/omega/ProcessTest.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2018 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.Bootstrap -import com.atlarge.opendc.simulator.Context -import com.atlarge.opendc.simulator.Process -import org.junit.jupiter.api.Test -import kotlin.coroutines.experimental.suspendCoroutine - -/** - * A test suite for processes in simulation. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -internal class ProcessTest { - object FreezeProcess : Process<Unit, Unit> { - override val initialState = Unit - override suspend fun Context<Unit, Unit>.run() { - receive() - suspendCoroutine<Unit> {} - } - } - - /** - * Test whether the simulation will not resume an already resumed continuation - * of a process. - */ - @Test - fun `simulation will not resume frozen process`() { - val bootstrap: Bootstrap<Unit> = Bootstrap.create { ctx -> - ctx.register(FreezeProcess) - ctx.schedule("Hello", destination = FreezeProcess, delay = 1) - ctx.schedule("Hello", destination = FreezeProcess, delay = 1) - } - val simulation = OmegaKernel.create(bootstrap) - simulation.run() - } -} diff --git a/opendc-kernel-omega/src/test/kotlin/com/atlarge/opendc/omega/SmokeTest.kt b/opendc-kernel-omega/src/test/kotlin/com/atlarge/opendc/omega/SmokeTest.kt deleted file mode 100644 index b056837c..00000000 --- a/opendc-kernel-omega/src/test/kotlin/com/atlarge/opendc/omega/SmokeTest.kt +++ /dev/null @@ -1,169 +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 com.atlarge.opendc.omega - -import com.atlarge.opendc.simulator.Bootstrap -import com.atlarge.opendc.simulator.Context -import com.atlarge.opendc.simulator.Process -import com.atlarge.opendc.simulator.instrumentation.Instrument -import com.atlarge.opendc.simulator.kernel.Simulation -import kotlinx.coroutines.experimental.Unconfined -import kotlinx.coroutines.experimental.async -import kotlinx.coroutines.experimental.channels.consumeEach -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows - -/** - * This test suite checks for smoke when running a large amount of simulations. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -internal class SmokeTest { - class EchoProcess : Process<Unit, Unit> { - override val initialState = Unit - override suspend fun Context<Unit, Unit>.run() { - while (true) { - val msg = receive() - sender?.send(msg) - } - } - } - - /** - * Run a large amount of simulations and test if any exceptions occur. - */ - @Test - fun smoke() { - val n = 1000 - 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(bootstrap) - simulation.run() - } - - object NullProcess : Process<Unit, Unit> { - override val initialState = Unit - override suspend fun Context<Unit, Unit>.run() {} - } - - /** - * 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 process = NullProcess - val bootstrap: Bootstrap<Unit> = Bootstrap.create { ctx -> - process.also { - ctx.register(it) - ctx.schedule(0, it) - } - } - - val simulation = OmegaKernel.create(bootstrap) - simulation.run() - } - - object CrashProcess : Process<Unit, Unit> { - override val initialState = Unit - override suspend fun Context<Unit, Unit>.run() { - throw RuntimeException("This process should crash") - } - } - - /** - * Test if the kernel allows sending messages to [Context] instances that have crashed. - */ - @Test - fun `sending message to process that has crashed`() { - val process = CrashProcess - val bootstrap: Bootstrap<Unit> = Bootstrap.create { ctx -> - process.also { - ctx.register(it) - ctx.schedule(0, it) - } - } - - val simulation = OmegaKernel.create(bootstrap) - assertThrows<RuntimeException> { simulation.run() } - } - - class ModelProcess(private val value: Int) : Process<Boolean, Int> { - override val initialState = false - override suspend fun Context<Boolean, Int>.run() { - assertEquals(value, model) - state = true - hold(10) - } - } - - /** - * Test if the kernel allows access to the simulation model object. - */ - @Test - fun `access simulation model`() { - val value = 1 - val process = ModelProcess(value) - val bootstrap: Bootstrap<Int> = Bootstrap.create { ctx -> - ctx.register(process) - value - } - - val kernel = OmegaKernel.create(bootstrap) - kernel.run(5) - } - - - @Test - fun `instrumentation works`() { - val instrument: Instrument<Int, Unit> = { - var value = 0 - - for (i in 1..10) { - send(value) - value += 10 - hold(20) - } - } - - val simulation: Simulation<Unit> = OmegaKernel.create(Bootstrap.create { Unit }) - val stream = simulation.openPort().install(instrument) - - val res = async(Unconfined) { - stream.consumeEach { println(it) } - } - simulation.run(100) - } -} diff --git a/opendc-model-odc/core/build.gradle b/opendc-model-odc/core/build.gradle deleted file mode 100644 index 091dcbe4..00000000 --- a/opendc-model-odc/core/build.gradle +++ /dev/null @@ -1,45 +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. - */ - -/* Build configuration */ -apply from: '../../gradle/kotlin.gradle' -apply plugin: 'java-library' - -/* Project configuration */ -repositories { - jcenter() -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib" - - api project(':opendc-core') - api project(':opendc-stdlib') - implementation "io.github.microutils:kotlin-logging:1.4.6" - - testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_jupiter_version" - testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_jupiter_version" - testImplementation "org.junit.platform:junit-platform-launcher:$junit_platform_version" - testRuntimeOnly "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 deleted file mode 100644 index 298a14cf..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/OdcModel.kt +++ /dev/null @@ -1,10 +0,0 @@ -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-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/FifoScheduler.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/FifoScheduler.kt deleted file mode 100644 index e743586c..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/FifoScheduler.kt +++ /dev/null @@ -1,118 +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 com.atlarge.opendc.model.odc.platform.scheduler - -import com.atlarge.opendc.model.odc.platform.workload.Task -import com.atlarge.opendc.model.odc.topology.machine.Machine -import com.atlarge.opendc.simulator.Context -import java.util.* - -/** - * A [Scheduler] that distributes work according to the first-in-first-out principle. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -class FifoScheduler : Scheduler { - /** - * The name of this scheduler. - */ - override val name: String = "FIFO" - - /** - * The set of machines the scheduler knows of. - */ - private val machines: MutableSet<Machine> = HashSet() - - /** - * The queue of [Task]s that need to be scheduled. - */ - private val queue: Queue<Task> = ArrayDeque() - - /** - * (Re)schedule the tasks submitted to the scheduler over the specified set of machines. - */ - override suspend fun <S, M> Context<S, M>.schedule() { - if (queue.isEmpty()) { - return - } - - // The tasks that need to be rescheduled - val rescheduled = ArrayDeque<Task>() - val iterator = queue.iterator() - - machines - .filter { it.state.status != Machine.Status.HALT } - .forEach { machine -> - while (iterator.hasNext()) { - val task = iterator.next() - - // TODO What to do with tasks that are not ready yet to be processed - if (!task.ready) { - iterator.remove() - rescheduled.add(task) - continue - } else if (task.finished) { - iterator.remove() - continue - } - - machine.send(task) - break - } - } - - // Reschedule all tasks that are not ready yet - while (!rescheduled.isEmpty()) { - queue.add(rescheduled.poll()) - } - } - - /** - * Submit a [Task] to this scheduler. - * - * @param task The task to submit to the scheduler. - */ - override fun submit(task: Task) { - queue.add(task) - } - - /** - * Register a [Machine] to this scheduler. - * - * @param machine The machine to register. - */ - override fun register(machine: Machine) { - machines.add(machine) - } - - /** - * Deregister a [Machine] from this scheduler. - * - * @param machine The machine to deregister. - */ - override fun deregister(machine: Machine) { - machines.remove(machine) - } -} diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/Scheduler.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/Scheduler.kt deleted file mode 100644 index 79486ee6..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/Scheduler.kt +++ /dev/null @@ -1,71 +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 com.atlarge.opendc.model.odc.platform.scheduler - -import com.atlarge.opendc.model.odc.platform.workload.Task -import com.atlarge.opendc.model.odc.topology.machine.Machine -import com.atlarge.opendc.simulator.Context -import com.atlarge.opendc.simulator.Entity - -/** - * A task scheduler that is coupled to an [Entity] in the topology of the cloud network. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Scheduler { - /** - * The name of this scheduler. - */ - val name: String - - /** - * (Re)schedule the tasks submitted to the scheduler over the specified set of machines. - * - * This method should be invoked at some interval to allow the scheduler to reschedule existing tasks and schedule - * new tasks. - */ - suspend fun <S, M> Context<S, M>.schedule() - - /** - * Submit a [Task] to this scheduler. - * - * @param task The task to submit to the scheduler. - */ - fun submit(task: Task) - - /** - * Register a [Machine] to this scheduler. - * - * @param machine The machine to register. - */ - fun register(machine: Machine) - - /** - * Deregister a [Machine] from this scheduler. - * - * @param machine The machine to deregister. - */ - fun deregister(machine: Machine) -} diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/SrtfScheduler.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/SrtfScheduler.kt deleted file mode 100644 index d3f067df..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/scheduler/SrtfScheduler.kt +++ /dev/null @@ -1,110 +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 com.atlarge.opendc.model.odc.platform.scheduler - -import com.atlarge.opendc.model.odc.platform.workload.Task -import com.atlarge.opendc.model.odc.topology.machine.Machine -import com.atlarge.opendc.simulator.Context -import java.util.* - -/** - * A [Scheduler] that distributes work according to the shortest job first policy. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -class SrtfScheduler : Scheduler { - /** - * The name of this scheduler. - */ - override val name: String = "SRTF" - - /** - * The set of machines the scheduler knows of. - */ - private val machines: MutableSet<Machine> = HashSet() - - /** - * The set of [Task]s that need to be scheduled. - */ - private val tasks: MutableSet<Task> = HashSet() - - /** - * (Re)schedule the tasks submitted to the scheduler over the specified set of machines. - */ - override suspend fun <S, M> Context<S, M>.schedule() { - if (tasks.isEmpty()) { - return - } - - val iterator = tasks.sortedBy { it.remaining }.iterator() - - machines - .filter { it.state.status != Machine.Status.HALT } - .forEach { machine -> - while (iterator.hasNext()) { - val task = iterator.next() - - // TODO What to do with tasks that are not ready yet to be processed - if (!task.ready) { - tasks.add(task) - continue - } else if (task.finished) { - tasks.remove(task) - continue - } - - machine.send(task) - break - } - } - } - - /** - * Submit a [Task] to this scheduler. - * - * @param task The task to submit to the scheduler. - */ - override fun submit(task: Task) { - tasks.add(task) - } - - /** - * Register a [Machine] to this scheduler. - * - * @param machine The machine to register. - */ - override fun register(machine: Machine) { - machines.add(machine) - } - - /** - * Deregister a [Machine] from this scheduler. - * - * @param machine The machine to deregister. - */ - override fun deregister(machine: Machine) { - machines.remove(machine) - } -} diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Task.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Task.kt deleted file mode 100644 index d68cceba..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/Task.kt +++ /dev/null @@ -1,92 +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 com.atlarge.opendc.model.odc.platform.workload - -import com.atlarge.opendc.model.odc.topology.machine.Machine -import com.atlarge.opendc.simulator.Instant - -/** - * A task that runs as part of a [Job] on a [Machine]. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Task { - /** - * The unique identifier of the task. - */ - val id: Int - - /** - * The amount of flops for this task. - */ - val flops: Long - - /** - * The dependencies of the task. - */ - val dependencies: Set<Task> - - /** - * A flag to indicate the task is parallelizable. - */ - val parallelizable: Boolean - - /** - * The remaining flops for this task. - */ - val remaining: Long - - /** - * The state of the task. - */ - val state: TaskState - - /** - * A flag to indicate whether the task is ready to be started. - */ - val ready: Boolean - get() = !dependencies.any { !it.finished } - - /** - * A flag to indicate whether the task has finished. - */ - val finished: Boolean - get() = state is TaskState.Finished - - /** - * This method is invoked when a task has arrived at a datacenter. - * - * @param time The moment in time the task has arrived at the datacenter. - */ - fun arrive(time: Instant) - - /** - * Consume the given amount of flops of this task. - * - * @param time The current moment in time of the consumption. - * @param flops The total amount of flops to consume. - */ - fun consume(time: Instant, flops: Long) -} diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/TaskState.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/TaskState.kt deleted file mode 100644 index 78963ca3..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/platform/workload/TaskState.kt +++ /dev/null @@ -1,72 +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 com.atlarge.opendc.model.odc.platform.workload - -import com.atlarge.opendc.simulator.Instant - - -/** - * This class hierarchy describes the states of a [Task]. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -sealed class TaskState { - /** - * A state to indicate the task has not yet arrived at the [Datacenter]. - */ - object Underway : TaskState() - - /** - * A state to indicate the task has arrived at the [Datacenter]. - * - * @property at The moment in time the task has arrived. - */ - data class Queued(val at: Instant) : TaskState() - - /** - * A state to indicate the task has started running on a machine. - * - * @property previous The previous state of the task. - * @property at The moment in time the task started. - */ - data class Running(val previous: Queued, val at: Instant) : TaskState() - - /** - * A state to indicate the task has finished. - * - * @property previous The previous state of the task. - * @property at The moment in time the task finished. - */ - data class Finished(val previous: Running, val at: Instant) : TaskState() - - /** - * A state to indicate the task has failed. - * - * @property previous The previous state of the task. - * @property at The moment in time the task failed. - * @property reason The reason of the failure. - */ - data class Failed(val previous: Running, val at: Instant, val reason: String) : TaskState() -} diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Datacenter.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Datacenter.kt deleted file mode 100644 index 7293d9f7..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Datacenter.kt +++ /dev/null @@ -1,107 +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 com.atlarge.opendc.model.odc.topology.container - -import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler -import com.atlarge.opendc.model.odc.platform.workload.Task -import com.atlarge.opendc.model.odc.platform.workload.TaskState -import com.atlarge.opendc.model.odc.topology.machine.Machine -import com.atlarge.opendc.model.topology.Topology -import com.atlarge.opendc.model.topology.destinations -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 mu.KotlinLogging -import java.util.* - -/** - * A representation of a facility used to house computer systems and associated components. - * - * @property scheduler The tasks scheduler the datacenter uses. - * @property interval The interval at which task will be (re)scheduled. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Datacenter : Process<Unit, Topology> { - /** - * The task scheduler the datacenter uses. - */ - val scheduler: Scheduler - - /** - * The interval at which task will be (re)scheduled. - */ - val interval: Duration - - /** - * 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.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. - */ - override suspend fun Context<Unit, Topology>.run() = model.run { - val logger = KotlinLogging.logger {} - - // The queue of messages to be processed after a cycle - val queue: Queue<Any> = ArrayDeque() - // Find all machines in the datacenter - val machines = outgoingEdges.destinations<Room>("room").asSequence() - .flatMap { it.outgoingEdges.destinations<Rack>("rack").asSequence() } - .flatMap { it.outgoingEdges.destinations<Machine>("machine").asSequence() }.toList() - - logger.info { "Initialising datacenter with ${machines.size} machines" } - - // Register all machines to the scheduler - machines.forEach(scheduler::register) - - while (true) { - // Context all messages in the queue - while (queue.isNotEmpty()) { - val msg = queue.poll() - if (msg is Task) { - if (msg.state != TaskState.Underway) { - logger.warn { "Received invalid task $msg"} - continue - } - msg.arrive(time) - scheduler.submit(msg) - } - } - // (Re)schedule the tasks - scheduler.run { schedule() } - - // Sleep a time quantum - hold(interval, queue) - } - } -} diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Rack.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Rack.kt deleted file mode 100644 index 42fdc9cf..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/container/Rack.kt +++ /dev/null @@ -1,36 +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 com.atlarge.opendc.model.odc.topology.container - -import com.atlarge.opendc.model.topology.Topology -import com.atlarge.opendc.simulator.Entity - -/** - * A type of physical steel and electronic framework that is designed to house servers, networking devices, cables and - * other datacenter computing equipment. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Rack : Entity<Unit, Topology> diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Cpu.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Cpu.kt deleted file mode 100644 index 58eacdc1..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Cpu.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 com.atlarge.opendc.model.odc.topology.machine - -/** - * A central processing unit. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Cpu : ProcessingUnit diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Gpu.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Gpu.kt deleted file mode 100644 index 84afc711..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Gpu.kt +++ /dev/null @@ -1,33 +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 com.atlarge.opendc.model.odc.topology.machine - -/** - * A graphics processing unit. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Gpu : ProcessingUnit - diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Machine.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Machine.kt deleted file mode 100644 index 642723f5..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/Machine.kt +++ /dev/null @@ -1,123 +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 com.atlarge.opendc.model.odc.topology.machine - -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.Context -import com.atlarge.opendc.simulator.Duration -import com.atlarge.opendc.simulator.Process -import mu.KotlinLogging - -/** - * A Physical Machine (PM) inside a rack of a datacenter. It has a speed, and can be given a workload on which it will - * work until finished or interrupted. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -open class Machine : Process<Machine.State, Topology> { - /** - * The logger instance to use for the simulator. - */ - private val logger = KotlinLogging.logger {} - - /** - * The status of a machine. - */ - enum class Status { - HALT, IDLE, RUNNING - } - - /** - * The shape of the state of a [Machine] entity. - * - * @property status The status of the machine. - * @property task The task assign to the machine. - * @property memory The memory usage of the machine (defaults to 50mb for the kernel) - * @property load The load on the machine (defaults to 0.0) - * @property temperature The temperature of the machine (defaults to 23 degrees Celcius) - */ - data class State(val status: Status, - val task: Task? = null, - val memory: Int = 50, - val load: Double = 0.0, - val temperature: Double = 23.0) - - /** - * The initial state of a [Machine] entity. - */ - override val initialState = State(Status.HALT) - - /** - * Run the simulation kernel for this entity. - */ - override suspend fun Context<State, Topology>.run() = model.run { - state = State(Status.IDLE) - - val interval: Duration = 10 - val cpus = outgoingEdges.destinations<Cpu>("cpu") - val speed = cpus.fold(0, { acc, cpu -> acc + cpu.clockRate * cpu.cores }) - - // Halt the machine if it has not processing units (see bug #4) - if (cpus.isEmpty()) { - state = State(Status.HALT) - return - } - - var task: Task = receiveTask() - state = State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0) - - while (true) { - if (task.finished) { - logger.info { "$id: Task ${task.id} finished. Machine idle at $time" } - state = State(Status.IDLE) - task = receiveTask() - } else { - task.consume(time, speed * delta) - } - - // Check if we have received a new order in the meantime. - val msg = receive(interval) - if (msg is Task) { - task = msg - state = State(Status.RUNNING, task, load = 1.0, memory = state.memory + 50, temperature = 30.0) - } - } - } - - /** - * 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<State, Topology>.receiveTask(): Task { - while (true) { - val msg = receive() - if (msg is Task) - return msg - } - } -} diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/ProcessingUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/ProcessingUnit.kt deleted file mode 100644 index e5d30173..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/machine/ProcessingUnit.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 com.atlarge.opendc.model.odc.topology.machine - -import com.atlarge.opendc.model.topology.Topology -import com.atlarge.opendc.simulator.Entity - -/** - * 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, Topology> { - /** - * The speed of this [ProcessingUnit] per core in MHz. - */ - val clockRate: Int - - /** - * The amount of cores within this [ProcessingUnit]. - */ - val cores: Int - - /** - * The energy consumption of this [ProcessingUnit] in Watt. - */ - val energyConsumption: Double -} diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/network/NetworkUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/network/NetworkUnit.kt deleted file mode 100644 index 5ffc19bf..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/network/NetworkUnit.kt +++ /dev/null @@ -1,35 +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 com.atlarge.opendc.model.odc.topology.network - -import com.atlarge.opendc.model.topology.Topology -import com.atlarge.opendc.simulator.Entity - -/** - * A generic interface for a network unit in a cloud network. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface NetworkUnit : Entity<Unit, Topology> diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/power/PowerUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/power/PowerUnit.kt deleted file mode 100644 index 3e9248c4..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/power/PowerUnit.kt +++ /dev/null @@ -1,35 +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 com.atlarge.opendc.model.odc.topology.power - -import com.atlarge.opendc.model.topology.Topology -import com.atlarge.opendc.simulator.Entity - -/** - * 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, Topology> diff --git a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/storage/StorageUnit.kt b/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/storage/StorageUnit.kt deleted file mode 100644 index eb622f2c..00000000 --- a/opendc-model-odc/core/src/main/kotlin/com/atlarge/opendc/model/odc/topology/storage/StorageUnit.kt +++ /dev/null @@ -1,35 +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 com.atlarge.opendc.model.odc.topology.storage - -import com.atlarge.opendc.model.topology.Topology -import com.atlarge.opendc.simulator.Entity - -/** - * A generic interface for a storage unit in a cloud network. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface StorageUnit : Entity<Unit, Topology> diff --git a/opendc-model-odc/jpa/build.gradle b/opendc-model-odc/jpa/build.gradle deleted file mode 100644 index 33b50d39..00000000 --- a/opendc-model-odc/jpa/build.gradle +++ /dev/null @@ -1,47 +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. - */ - -/* Build configuration */ -apply from: '../../gradle/kotlin.gradle' -apply plugin: 'java-library' -apply plugin: 'kotlin-jpa' - -/* Project configuration */ -repositories { - jcenter() -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib" - - api project(':opendc-core') - api project(':opendc-stdlib') - api project(':opendc-model-odc:core') - api "javax.persistence:javax.persistence-api:2.2" - implementation "io.github.microutils:kotlin-logging:1.4.6" - - testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_jupiter_version" - testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_jupiter_version" - testImplementation "org.junit.platform:junit-platform-launcher:$junit_platform_version" -} 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 deleted file mode 100644 index 9cb37dc9..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaBootstrap.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.atlarge.opendc.model.odc - -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 -import com.atlarge.opendc.simulator.Bootstrap -import mu.KotlinLogging - -/** - * 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> { - /** - * The logging instance. - */ - private val logger = KotlinLogging.logger {} - - /** - * Bootstrap a model `M` for a kernel in the given context. - * - * @param context The context to apply to model in. - * @return The initialised model for the simulation. - */ - override fun apply(context: Bootstrap.Context<JpaModel>): JpaModel { - val section = experiment.path.sections.first() - - // TODO We should not modify parts of the experiment in a apply as the apply should be reproducible. - // Important: initialise the scheduler of the datacenter - section.datacenter.scheduler = experiment.scheduler - - val topology = JpaTopologyFactory(section) - .create() - .bootstrap() - .apply(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 deleted file mode 100644 index 44c1fb69..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/JpaModel.kt +++ /dev/null @@ -1,14 +0,0 @@ -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-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/Jpa.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/Jpa.kt deleted file mode 100644 index 3a9805d5..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/Jpa.kt +++ /dev/null @@ -1,85 +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 com.atlarge.opendc.model.odc.integration.jpa - -import kotlinx.coroutines.experimental.channels.ReceiveChannel -import kotlinx.coroutines.experimental.channels.consume -import javax.persistence.EntityManager -import javax.persistence.EntityManagerFactory -import javax.persistence.RollbackException - -/** - * Run the given block in a transaction, committing on return of the block. - * - * @param block The block to execute in the transaction. - */ -inline fun EntityManager.transaction(block: () -> Unit) { - transaction.begin() - block() - transaction.commit() -} - -/** - * Write the given channel in batch to the database. - * - * @param factory The [EntityManagerFactory] to use to create an [EntityManager] which can persist the entities. - * @param batchSize The size of each batch. - */ -suspend fun <E> ReceiveChannel<E>.persist(factory: EntityManagerFactory, batchSize: Int = 1000) { - val writer = factory.createEntityManager() - - this.consume { - val transaction = writer.transaction - var counter = 0 - try { - transaction.begin() - - for (element in this) { - // Commit batch every batch size - if (counter > 0 && counter % batchSize == 0) { - writer.flush() - writer.clear() - - transaction.commit() - transaction.begin() - } - - writer.persist(element) - counter++ - } - - transaction.commit() - } catch(e: RollbackException) { - // Rollback transaction if still active - if (transaction.isActive) { - transaction.rollback() - } - - throw e - } finally { - writer.close() - } - } -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/ParallelizableConverter.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/ParallelizableConverter.kt deleted file mode 100644 index e9635b2e..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/ParallelizableConverter.kt +++ /dev/null @@ -1,62 +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 com.atlarge.opendc.model.odc.integration.jpa.converter - -import javax.persistence.AttributeConverter - -/** - * An internal [AttributeConverter] that maps the values _PARALLEL_ and _SEQUENTIAL_ to a - * boolean value indicating whether a task is parallelizable. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -class ParallelizableConverter : AttributeConverter<Boolean, String> { - /** - * Converts the data stored in the database column into the - * value to be stored in the entity attribute. - * Note that it is the responsibility of the converter writer to - * specify the correct dbData type for the corresponding column - * for use by the JDBC driver: i.e., persistence providers are - * not expected to do such type conversion. - * - * @param dbData the data from the database column to be converted - * @return the converted value to be stored in the entity attribute - */ - override fun convertToEntityAttribute(dbData: String?): Boolean = when (dbData?.toUpperCase()) { - "SEQUENTIAL" -> false - "PARALLEL" -> true - else -> false - } - - /** - * Converts the value stored in the entity attribute into the - * data representation to be stored in the database. - * - * @param attribute the entity attribute value to be converted - * @return the converted data to be stored in the database column - */ - override fun convertToDatabaseColumn(attribute: Boolean?): String = - if (attribute == true) "PARALLEL" else "SEQUENTIAL" -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/SchedulerConverter.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/SchedulerConverter.kt deleted file mode 100644 index 15f6a905..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/converter/SchedulerConverter.kt +++ /dev/null @@ -1,66 +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 com.atlarge.opendc.model.odc.integration.jpa.converter - -import com.atlarge.opendc.model.odc.platform.scheduler.FifoScheduler -import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler -import com.atlarge.opendc.model.odc.platform.scheduler.SrtfScheduler -import javax.persistence.AttributeConverter - -/** - * An internal [AttributeConverter] that maps a name of a scheduler to the actual scheduler implementation. - * The converter currently chooses between the following two schedulers: - * - [FifoScheduler] (default) - * - [SrtfScheduler] - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -class SchedulerConverter : AttributeConverter<Scheduler, String> { - /** - * Converts the data stored in the database column into the - * value to be stored in the entity attribute. - * Note that it is the responsibility of the converter writer to - * specify the correct dbData type for the corresponding column - * for use by the JDBC driver: i.e., persistence providers are - * not expected to do such type conversion. - * - * @param dbData the data from the database column to be converted - * @return the converted value to be stored in the entity attribute - */ - override fun convertToEntityAttribute(dbData: String?): Scheduler = when (dbData?.toUpperCase()) { - "SRTF" -> SrtfScheduler() - else -> FifoScheduler() - } - - /** - * Converts the value stored in the entity attribute into the - * data representation to be stored in the database. - * - * @param attribute the entity attribute value to be converted - * @return the converted data to be stored in the database column - */ - override fun convertToDatabaseColumn(attribute: Scheduler?): String = - attribute?.name?.toUpperCase() ?: "FIFO" -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Cpu.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Cpu.kt deleted file mode 100644 index 11553477..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Cpu.kt +++ /dev/null @@ -1,58 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.model.odc.topology.machine.Cpu -import javax.persistence.Entity - -/** - * A cpu entity in the persistent schema. - * - * @property id The unique identifier of the cpu. - * @property manufacturer The manufacturer of the cpu. - * @property family The family of the cpu. - * @property generation The generation of the cpu. - * @property model The model of the cpu. - * @property clockRate The clock rate of the cpu. - * @property cores The amount of cores in the gpu. - * @property energyConsumption The energy consumption of the cpu in Watt. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class Cpu( - val id: Int, - val manufacturer: String, - val family: String, - val generation: String, - val model: String, - override val clockRate: Int, - override val cores: Int, - override val energyConsumption: Double -) : Cpu { - /** - * The initial state of the entity. - */ - override val initialState = Unit -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Datacenter.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Datacenter.kt deleted file mode 100644 index e65eef8b..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Datacenter.kt +++ /dev/null @@ -1,66 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler -import com.atlarge.opendc.model.odc.topology.container.Datacenter -import com.atlarge.opendc.simulator.Duration -import javax.persistence.Entity - -/** - * A datacenter entity in the persistent schema. - * - * @property id The unique identifier of the datacenter. - * @property rooms The rooms in the datacenter. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class Datacenter( - val id: Int, - val rooms: Set<Room> -) : Datacenter { - /** - * Construct a datacenter. We need this useless constructor in order for Kotlin correctly initialise the - * constant fields of the class. - */ - private constructor() : this(-1, emptySet()) - - /** - * The task scheduler the datacenter uses. - */ - override lateinit var scheduler: Scheduler - internal set - - /** - * The interval at which task will be (re)scheduled. - * We set this to a fixed constant since the database provides no way of configuring this. - */ - override val interval: Duration = 10 - - /** - * The initial state of the datacenter. - */ - override val initialState = Unit -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Experiment.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Experiment.kt deleted file mode 100644 index ce489b1f..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Experiment.kt +++ /dev/null @@ -1,58 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.model.odc.platform.scheduler.Scheduler -import com.atlarge.opendc.simulator.Instant -import javax.persistence.Entity - -/** - * An experiment definition for the OpenDC database schema. - * - * @property id The identifier of the experiment. - * @property name The name of the experiment. - * @property scheduler The scheduler used in the experiment. - * @property trace The trace used for the simulation. - * @property path The path of the experiment. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class Experiment( - val id: Int, - val name: String, - val scheduler: Scheduler, - val trace: Trace, - val path: Path -) { - /** - * The state of the experiment. - */ - var state: ExperimentState = ExperimentState.QUEUED - - /** - * The last tick that has been simulated. - */ - var last: Instant = 0 -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Gpu.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Gpu.kt deleted file mode 100644 index c04262cc..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Gpu.kt +++ /dev/null @@ -1,58 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.model.odc.topology.machine.Gpu -import javax.persistence.Entity - -/** - * A gpu entity in the persistent schema. - * - * @property id The unique identifier of the gpu. - * @property manufacturer The manufacturer of the gpu. - * @property family The family of the gpu. - * @property generation The generation of the gpu. - * @property model The model of the gpu. - * @property clockRate The clock rate of the gpu. - * @property cores The amount of cores in the gpu. - * @property energyConsumption The energy consumption of the gpu in Watt. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class Gpu( - val id: Int, - val manufacturer: String, - val family: String, - val generation: String, - val model: String, - override val clockRate: Int, - override val cores: Int, - override val energyConsumption: Double -) : Gpu { - /** - * The initial state of the entity. - */ - override val initialState = Unit -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Job.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Job.kt deleted file mode 100644 index 67ffba32..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Job.kt +++ /dev/null @@ -1,58 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.model.odc.platform.workload.Job -import com.atlarge.opendc.model.odc.platform.workload.User -import javax.persistence.Entity - -/** - * A [Job] backed by the JPA API and an underlying database connection. - * - * @property id The unique identifier of the job. - * @property tasks The collection of tasks the job consists of. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class Job( - override val id: Int, - override val tasks: Set<Task> -) : Job { - /** - * The owner of the job, which is a singleton, since the database has no - * concept of ownership yet. - */ - override val owner: User = object : User { - /** - * The unique identifier of the user. - */ - override val id: Int = 0 - - /** - * The name of this user. - */ - override val name: String = "admin" - } -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Machine.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Machine.kt deleted file mode 100644 index 925ab1d2..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Machine.kt +++ /dev/null @@ -1,45 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.model.odc.topology.machine.Machine -import javax.persistence.Entity - -/** - * A machine entity in the persistent schema. - * - * @property id The unique identifier of the machine. - * @property position The position of the machine in the rack. - * @property cpus The CPUs in the machine. - * @property gpus The GPUs in the machine. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class Machine( - val id: Int, - val position: Int, - val cpus: Set<Cpu>, - val gpus: Set<Gpu> -) : Machine() diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/MachineState.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/MachineState.kt deleted file mode 100644 index 18c8d5cc..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/MachineState.kt +++ /dev/null @@ -1,80 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.simulator.Instant -import com.atlarge.opendc.simulator.instrumentation.interpolate -import com.atlarge.opendc.simulator.instrumentation.lerp -import kotlinx.coroutines.experimental.Unconfined -import kotlinx.coroutines.experimental.channels.ReceiveChannel -import kotlinx.coroutines.experimental.channels.consume -import javax.persistence.Entity -import kotlin.coroutines.experimental.CoroutineContext - -/** - * The state of a [Machine]. - * - * @property id The unique identifier of the state. - * @property machine The machine of the state. - * @property task The task the machine has been assigned. - * @property experiment The experiment the machine is running in. - * @property time The current moment in time. - * @property temperature The temperature of the machine. - * @property memoryUsage The memory usage of the machine. - * @property load The load of the machine. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class MachineState( - val id: Int, - val machine: Machine, - val task: Task?, - val experiment: Experiment, - val time: Instant, - val temperature: Double, - val memoryUsage: Int, - val load: Double -) - -/** - * Linearly interpolate [n] amount of elements between every two occurrences of task progress measurements represented - * as [MachineState] instances passing through the channel. - * - * The operation is _intermediate_ and _stateless_. - * This function [consumes][consume] all elements of the original [ReceiveChannel]. - * - * @param context The context of the coroutine. - * @param n The amount of elements to interpolate between the actual elements in the channel. - */ -fun ReceiveChannel<MachineState>.interpolate(n: Int, context: CoroutineContext = Unconfined): ReceiveChannel<MachineState> = - interpolate(n, context) { f, a, b -> - a.copy( - id = 0, - time = lerp(a.time, b.time, f), - temperature = lerp(a.temperature, b.temperature, f), - memoryUsage = lerp(a.memoryUsage, b.memoryUsage, f), - load = lerp(a.load, b.load, f) - ) - } diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Path.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Path.kt deleted file mode 100644 index a6e915f3..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Path.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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import javax.persistence.Entity - -/** - * A [Path] holds all sections of the parent experiment. - * - * @property id The unique identifier of the path. - * @property sections The sections of the path. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -open class Path( - val id: Int, - val sections: List<Section> -) diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Rack.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Rack.kt deleted file mode 100644 index dd48480d..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Rack.kt +++ /dev/null @@ -1,52 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.model.odc.topology.container.Rack -import javax.persistence.Entity - -/** - * A rack entity in a room in the persistent schema. - * - * @property id The unique identifier of the rack. - * @property name The name of the rack. - * @property capacity The capacity of the rack in terms of units. - * @property powerCapacity The power capacity of the rack in Watt. - * @property machines The machines in the rack. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -class Rack( - id: Int, - val name: String, - val capacity: Int, - val powerCapacity: Int, - val machines: List<Machine> -) : RoomObject(id), Rack { - /** - * The initial state of the entity. - */ - override val initialState = Unit -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Room.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Room.kt deleted file mode 100644 index 1a1c721f..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Room.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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.model.odc.topology.container.Room -import javax.persistence.Entity - -/** - * A room entity in the persistent schema. - * - * @property id The unique identifier of the room. - * @property name The name of the room. - * @property type The type of the room. - * @property objects The objects in the room. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class Room( - val id: Int, - val name: String, - val type: RoomType, - val objects: Set<RoomObject> -) : Room { - /** - * The initial state of the entity. - */ - override val initialState = Unit -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomObject.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomObject.kt deleted file mode 100644 index 49db076c..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomObject.kt +++ /dev/null @@ -1,36 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import javax.persistence.Entity - -/** - * An object in a room. - * - * @property id The unique identifier of the room. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -abstract class RoomObject(val id: Int) diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomType.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomType.kt deleted file mode 100644 index ed0f89d3..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/RoomType.kt +++ /dev/null @@ -1,34 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -/** - * This enumeration defines the room types available in the OpenDC frontend. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -enum class RoomType { - COOLING, HALLWAY, OFFICE, POWER, SERVER -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Section.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Section.kt deleted file mode 100644 index c6de2e50..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Section.kt +++ /dev/null @@ -1,45 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.simulator.Instant -import javax.persistence.Entity - -/** - * A [Section] holds a datacenter and the tick on which the parent experiment should - * switch to this section. - * - * @property id The unique identifier of the section. - * @property datacenter The datacenter of this section. - * @property startTime The position in time when the experiment should start using the - * topology of this section. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class Section( - val id: Int, - val datacenter: Datacenter, - val startTime: Instant -) diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Task.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Task.kt deleted file mode 100644 index 4a296255..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Task.kt +++ /dev/null @@ -1,118 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.model.odc.platform.workload.Task -import com.atlarge.opendc.model.odc.platform.workload.TaskState -import com.atlarge.opendc.simulator.Instant -import javax.persistence.Entity -import javax.persistence.PostLoad - -/** - * A [Task] backed by the JPA API and an underlying database connection. - * - * @property id The unique identifier of the job. - * @property flops The total amount of flops for the task. - * @property dependency A dependency on another task. - * @property parallelizable A flag to indicate the task is parallelizable. - * @property startTime The start time in the simulation. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class Task( - override val id: Int, - override val flops: Long, - private val dependency: Task?, - override val parallelizable: Boolean, - val startTime: Instant -) : Task { - /** - * The dependencies of the task. - */ - override lateinit var dependencies: Set<Task> - private set - - /** - * The remaining flops for this task. - */ - override var remaining: Long = 0 - private set - - /** - * A flag to indicate whether the task has finished. - */ - override var finished: Boolean = false - private set - - /** - * The state of the task. - */ - override lateinit var state: TaskState - private set - - /** - * This method initialises the task object after it has been created by the JPA implementation. We use this - * initialisation method because JPA implementations only call the default constructor - */ - @PostLoad - internal fun init() { - remaining = flops - dependencies = dependency?.let(::setOf) ?: emptySet() - state = TaskState.Underway - } - - /** - * This method is invoked when a task has arrived at a datacenter. - * - * @param time The moment in time the task has arrived at the datacenter. - */ - override fun arrive(time: Instant) { - if (state !is TaskState.Underway) { - throw IllegalStateException("The task has already been submitted to a datacenter") - } - remaining = flops - state = TaskState.Queued(time) - } - - /** - * Consume the given amount of flops of this task. - * - * @param time The current moment in time of the consumption. - * @param flops The total amount of flops to consume. - */ - override fun consume(time: Instant, flops: Long) { - if (state is TaskState.Queued) { - state = TaskState.Running(state as TaskState.Queued, time) - } else if (finished) { - return - } - remaining -= flops - if (remaining <= 0) { - remaining = 0 - finished = true - state = TaskState.Finished(state as TaskState.Running, time) - } - } -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/TaskState.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/TaskState.kt deleted file mode 100644 index b010229d..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/TaskState.kt +++ /dev/null @@ -1,74 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.simulator.Instant -import com.atlarge.opendc.simulator.instrumentation.interpolate -import com.atlarge.opendc.simulator.instrumentation.lerp -import kotlinx.coroutines.experimental.Unconfined -import kotlinx.coroutines.experimental.channels.ReceiveChannel -import kotlinx.coroutines.experimental.channels.consume -import javax.persistence.Entity -import kotlin.coroutines.experimental.CoroutineContext - -/** - * The state of a [Task]. - * - * @property id The unique identifier of the state. - * @property task The task this is the state of. - * @property experiment The experiment the machine is running in. - * @property time The current moment in time. - * @property remaining The remaining flops for the task. - * @property cores The cores used for the task. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class TaskState( - val id: Int, - val task: Task, - val experiment: Experiment, - val time: Instant, - val remaining: Int, - val cores: Int -) - -/** - * Linearly interpolate [n] amount of elements between every two occurrences of task progress measurements represented - * as [TaskState] instances passing through the channel. - * - * The operation is _intermediate_ and _stateless_. - * This function [consumes][consume] all elements of the original [ReceiveChannel]. - * - * @param context The context of the coroutine. - * @param n The amount of elements to interpolate between the actual elements in the channel. - */ -fun ReceiveChannel<TaskState>.interpolate(n: Int, context: CoroutineContext = Unconfined): ReceiveChannel<TaskState> = - interpolate(n, context) { f, a, b -> - a.copy( - id = 0, - time = lerp(a.time, b.time, f), - remaining = lerp(a.remaining, b.remaining, f) - ) - } diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Trace.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Trace.kt deleted file mode 100644 index e2ed78a2..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/integration/jpa/schema/Trace.kt +++ /dev/null @@ -1,44 +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 com.atlarge.opendc.model.odc.integration.jpa.schema - -import com.atlarge.opendc.model.odc.platform.workload.Job -import com.atlarge.opendc.model.odc.platform.workload.Trace -import javax.persistence.Entity - -/** - * A [Trace] backed by the JPA API and an underlying database connection. - * - * @property id The unique identifier of the trace. - * @property name The name of the trace. - * @property jobs The collection of jobs for this trace. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -@Entity -data class Trace( - val id: Int, - val name: String, - override val jobs: Set<Job> -) : Trace diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperiment.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperiment.kt deleted file mode 100644 index 9aeb0066..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperiment.kt +++ /dev/null @@ -1,254 +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 com.atlarge.opendc.model.odc.platform - -import com.atlarge.opendc.model.odc.JpaBootstrap -import com.atlarge.opendc.model.odc.JpaModel -import com.atlarge.opendc.model.odc.integration.jpa.persist -import com.atlarge.opendc.model.odc.integration.jpa.schema.ExperimentState -import com.atlarge.opendc.model.odc.integration.jpa.schema.interpolate -import com.atlarge.opendc.model.odc.integration.jpa.schema.MachineState -import com.atlarge.opendc.model.odc.integration.jpa.transaction -import com.atlarge.opendc.model.odc.platform.workload.Task -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.model.topology.destinations -import com.atlarge.opendc.simulator.Duration -import com.atlarge.opendc.simulator.instrumentation.* -import com.atlarge.opendc.simulator.kernel.Kernel -import com.atlarge.opendc.simulator.platform.Experiment -import kotlinx.coroutines.experimental.channels.Channel -import kotlinx.coroutines.experimental.channels.asReceiveChannel -import kotlinx.coroutines.experimental.channels.map -import kotlinx.coroutines.experimental.launch -import kotlinx.coroutines.experimental.runBlocking -import mu.KotlinLogging -import java.io.Closeable -import javax.persistence.EntityManager -import kotlin.coroutines.experimental.coroutineContext -import kotlin.system.measureTimeMillis -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.model.odc.integration.jpa.schema.TaskState as InternalTaskState -import com.atlarge.opendc.model.odc.integration.jpa.schema.Trace as InternalTrace - -/** - * An [Experiment] backed by the JPA API and an underlying database connection. - * - * @property manager The entity manager for the database connection. - * @property experiment The internal experiment definition to use. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -class JpaExperiment(private val manager: EntityManager, - private val experiment: InternalExperiment) : Experiment<Unit>, Closeable { - /** - * The logging instance. - */ - private val logger = KotlinLogging.logger {} - - /** - * Run the experiment using the specified simulation kernel implementation. - * - * @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(factory: Kernel, timeout: Duration): Unit? { - if (experiment.state != ExperimentState.CLAIMED) { - throw IllegalStateException("The experiment is in illegal state ${experiment.state}") - } - - logger.info { "Initialising experiment ${experiment.id}" } - - // Set the simulation state - manager.transaction { - experiment.state = ExperimentState.SIMULATING - } - - val bootstrap = JpaBootstrap(experiment) - val simulation = factory.create(bootstrap) - - val section = experiment.path.sections.first() - val trace = experiment.trace - val tasks = trace.jobs.flatMap { it.tasks } - - // The port we use to install the instruments - val port = simulation.openPort() - - // Find all machines in the datacenter - val machines = simulation.model.run { - section.datacenter.outgoingEdges.destinations<Room>("room").asSequence() - .flatMap { it.outgoingEdges.destinations<Rack>("rack").asSequence() } - .flatMap { it.outgoingEdges.destinations<Machine>("machine").asSequence() }.toList() - } - - // The instrument used for monitoring machines - fun machine(machine: Machine): Instrument<MachineState, JpaModel> = { - while (true) { - send(MachineState( - 0, - machine as com.atlarge.opendc.model.odc.integration.jpa.schema.Machine, - machine.state.task as InternalTask?, - experiment, - time, - machine.state.temperature, - machine.state.memory, - machine.state.load - )) - hold(10) - } - } - - // The stream of machine state measurements - val machineStates = machines - .asReceiveChannel() - .map { machine(it) } - .flatMapMerge { port.install(Channel.UNLIMITED, it).interpolate(9) } - - // The instrument used for monitoring tasks - fun task(task: Task): Instrument<InternalTaskState, JpaModel> = { - while (true) { - send(InternalTaskState( - 0, - task as InternalTask, - experiment, - time, - task.remaining.toInt(), - 1 - )) - - hold(10) - } - } - - // The stream of task state measurements - val taskStates = tasks - .asReceiveChannel() - .map { task(it) } - .flatMapMerge { port.install(it).interpolate(9) } - - // A job which writes the data to database in a separate thread - val writer = launch { - taskStates.merge(coroutineContext, machineStates) - .persist(manager.entityManagerFactory) - } - - // A method to flush the remaining measurements to the database - fun finalize() = runBlocking { - logger.info { "Flushing remaining measurements to database" } - - // Stop gathering new measurements - port.close() - - // Wait for writer thread to finish - writer.join() - } - - logger.info { "Starting simulation" } - logger.info { "Scheduling total of ${trace.jobs.size} jobs and ${tasks.size} tasks" } - - val measurement = measureTimeMillis { - while (true) { - // Have all jobs finished yet - if (trace.jobs.all { it.finished }) - break - - // If we have reached a timeout, return - if (simulation.time >= timeout) { - // Flush remaining data - finalize() - - // Mark the experiment as aborted - manager.transaction { - experiment.last = simulation.time - experiment.state = ExperimentState.ABORTED - } - - logger.warn { "Experiment aborted due to timeout" } - return null - } - - try { - // Run next simulation cycle - simulation.step() - } catch (e: Throwable) { - logger.error(e) { "An error occurred during execution of the experiment" } - } - } - } - - logger.info { "Simulation done in $measurement milliseconds" } - - // Flush remaining data to database - finalize() - - // Mark experiment as finished - manager.transaction { - experiment.last = simulation.time - experiment.state = ExperimentState.FINISHED - } - - logger.info { "Computing statistics" } - val waiting: Long = tasks.fold(0.toLong()) { acc, task -> - val finished = task.state as TaskState.Finished - acc + (finished.previous.at - finished.previous.previous.at) - } / tasks.size - - val execution: Long = tasks.fold(0.toLong()) { acc, task -> - val finished = task.state as TaskState.Finished - acc + (finished.at - finished.previous.at) - } / tasks.size - - val turnaround: Long = tasks.fold(0.toLong()) { acc, task -> - val finished = task.state as TaskState.Finished - acc + (finished.at - finished.previous.previous.at) - } / tasks.size - - logger.info { "Average waiting time: $waiting seconds" } - logger.info { "Average execution time: $execution seconds" } - logger.info { "Average turnaround time: $turnaround seconds" } - - return Unit - } - - /** - * Run the experiment on the specified simulation kernel implementation. - * - * @param factory The factory to create the simulation kernel with. - * @throws IllegalStateException if the simulation is already running or finished. - */ - override fun run(factory: Kernel) = run(factory, -1)!! - - /** - * Closes this resource, relinquishing any underlying resources. - * This method is invoked automatically on objects managed by the - * `try`-with-resources statement. - * - * @throws Exception if this resource cannot be closed - */ - override fun close() = manager.close() -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperimentManager.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperimentManager.kt deleted file mode 100644 index 5dbb9a8b..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaExperimentManager.kt +++ /dev/null @@ -1,93 +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 com.atlarge.opendc.model.odc.platform - -import com.atlarge.opendc.model.odc.integration.jpa.schema.ExperimentState -import com.atlarge.opendc.model.odc.integration.jpa.transaction -import com.atlarge.opendc.simulator.platform.Experiment -import javax.persistence.EntityManager -import javax.persistence.EntityManagerFactory -import com.atlarge.opendc.model.odc.integration.jpa.schema.Experiment as InternalExperiment - -/** - * A manager for [Experiment]s received from a JPA database. - * - * @property factory The JPA entity manager factory to create [EntityManager]s to retrieve entities from the database - * from. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -class JpaExperimentManager(private val factory: EntityManagerFactory) : AutoCloseable { - /** - * The entity manager for this experiment. - */ - private var manager: EntityManager = factory.createEntityManager() - - /** - * The amount of experiments in the queue. This property is not guaranteed to run in constant time. - */ - val size: Int - get() { - return manager.createQuery("SELECT COUNT(e.id) FROM experiments e WHERE e.state = :s", - java.lang.Long::class.java) - .setParameter("s", ExperimentState.QUEUED) - .singleResult.toInt() - } - - /** - * Poll an [Experiment] from the database and claim it. - * - * @return The experiment that has been polled from the database or `null` if there are no experiments in the - * queue. - */ - fun poll(): JpaExperiment? { - var result: JpaExperiment? = null - manager.transaction { - var experiment: InternalExperiment? = null - val results = manager.createQuery("SELECT e FROM experiments e WHERE e.state = :s", - InternalExperiment::class.java) - .setParameter("s", ExperimentState.QUEUED) - .setMaxResults(1) - .resultList - - - if (!results.isEmpty()) { - experiment = results.first() - experiment!!.state = ExperimentState.CLAIMED - } - result = experiment?.let { JpaExperiment(manager, it) } - } - manager = factory.createEntityManager() - return result - } - - /** - * Close this resource, relinquishing any underlying resources. - * This method is invoked automatically on objects managed by the - * `try`-with-resources statement.* - * - * @throws Exception if this resource cannot be closed - */ - override fun close() = manager.close() -} diff --git a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/topology/JpaTopologyFactory.kt b/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/topology/JpaTopologyFactory.kt deleted file mode 100644 index 65961413..00000000 --- a/opendc-model-odc/jpa/src/main/kotlin/com/atlarge/opendc/model/odc/topology/JpaTopologyFactory.kt +++ /dev/null @@ -1,91 +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 com.atlarge.opendc.model.odc.topology - -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.* - -/** - * A [TopologyFactory] that converts a [Section] of an experiment as defined by the API, into a proper [Topology]. - * - * @property section The section to convert into a topology. - * @property builder A builder for a topology to use. - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -class JpaTopologyFactory(val section: Section, val builder: TopologyBuilder = AdjacencyList.builder()) : TopologyFactory { - /** - * Create a [MutableTopology] instance. - * - * @return A mutable topology. - */ - override fun create(): MutableTopology = builder.construct { - val datacenter = section.datacenter - add(datacenter) - datacenter.rooms.forEach { room -> - add(room) - connect(datacenter, room, tag = "room") - - room.objects.forEach { roomObject(room, it) } - } - } - - /** - * Handle the objects in a room. - * - * @param obj The obj to handle. - */ - private fun MutableTopology.roomObject(parent: Room, obj: RoomObject) = when (obj) { - is Rack -> rack(parent, obj) - else -> Unit - } - - /** - * Handle a rack in a room. - * - * @param parent The parent of the rack. - * @param rack The rack to handle. - */ - private fun MutableTopology.rack(parent: Room, rack: Rack) { - add(rack) - connect(parent, rack, tag = "rack") - rack.machines.forEach { machine -> - add(machine) - connect(rack, machine, tag = "machine") - - machine.cpus.forEach { cpu -> - add(cpu) - connect(machine, cpu, tag = "cpu") - } - - machine.gpus.forEach { gpu -> - add(gpu) - connect(machine, gpu, tag = "gpu") - } - } - } -} diff --git a/opendc-model-odc/jpa/src/main/resources/jpa/schema.xml b/opendc-model-odc/jpa/src/main/resources/jpa/schema.xml deleted file mode 100644 index 887cc8ab..00000000 --- a/opendc-model-odc/jpa/src/main/resources/jpa/schema.xml +++ /dev/null @@ -1,326 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ 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. - --> -<entity-mappings - version="2.1" - xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm" -> - - <package>com.atlarge.opendc.model.odc.integration.jpa.schema</package> - - <entity class="Experiment" access="FIELD" name="experiments"> - <convert converter="com.atlarge.opendc.model.odc.integration.jpa.converter.SchedulerConverter" - attribute-name="scheduler"/> - <attributes> - <id name="id"/> - - <basic name="name"> - <column column-definition="text"/> - </basic> - - <basic name="state"> - <column column-definition="text"/> - <enumerated>STRING</enumerated> - </basic> - - <basic name="last"> - <column name="last_simulated_tick" column-definition="int(11)"/> - </basic> - - <basic name="scheduler"> - <column name="scheduler_name"/> - </basic> - - <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="com.atlarge.opendc.model.odc.integration.jpa.schema.Path"> - <join-column name="path_id"/> - </one-to-one> - </attributes> - </entity> - - <entity class="Path" access="FIELD" name="paths"> - <attributes> - <id name="id"/> - - <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> - </entity> - - <entity class="Section" access="FIELD" name="sections"> - <attributes> - <id name="id"/> - - <basic name="startTime"> - <column name="start_tick" column-definition="int(11)"/> - </basic> - - <many-to-one name="datacenter"> - <join-column name="datacenter_id"/> - </many-to-one> - </attributes> - </entity> - - <entity class="Trace" access="FIELD" name="traces" cacheable="false"> - <attributes> - <id name="id"/> - <basic name="name"> - <column column-definition="text"/> - </basic> - <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> - </entity> - - <entity class="Job" access="FIELD" name="jobs" cacheable="false"> - <attributes> - <id name="id"/> - <one-to-many name="tasks" target-entity="Task"> - <join-column name="job_id"/> - </one-to-many> - <transient name="owner"/> - </attributes> - </entity> - - <entity class="Task" access="FIELD" name="tasks" cacheable="false"> - <convert converter="com.atlarge.opendc.model.odc.integration.jpa.converter.ParallelizableConverter" - attribute-name="parallelizable"/> - <attributes> - <id name="id"/> - <basic name="flops"> - <column name="total_flop_count" column-definition="int(11)"/> - </basic> - <basic name="startTime"> - <column name="start_tick" column-definition="int(11)"/> - </basic> - <basic name="parallelizable"> - <column name="parallelizability" column-definition="text"/> - </basic> - - <one-to-one name="dependency" target-entity="Task"> - <join-column name="task_dependency_id"/> - </one-to-one> - <transient name="dependencies"/> - <transient name="state"/> - <transient name="remaining"/> - <transient name="finished"/> - </attributes> - </entity> - - <entity class="Datacenter" access="FIELD" name="datacenters"> - <attributes> - <id name="id"/> - - <one-to-many name="rooms" target-entity="Room"> - <join-column name="datacenter_id"/> - </one-to-many> - <transient name="scheduler"/> - <transient name="interval"/> - <transient name="initialState"/> - </attributes> - </entity> - - <entity class="Room" access="FIELD" name="rooms"> - <attributes> - <id name="id"/> - <basic name="name"> - <column column-definition="text"/> - </basic> - <basic name="type"> - <enumerated>STRING</enumerated> - </basic> - <one-to-many name="objects"> - <join-table name="tiles"> - <join-column name="room_id"/> - <inverse-join-column name="object_id"/> - </join-table> - </one-to-many> - <transient name="initialState"/> - </attributes> - </entity> - - <entity class="RoomObject" access="FIELD" name="objects"> - <inheritance strategy="JOINED"/> - <discriminator-column name="type"/> - <attributes> - <id name="id"/> - </attributes> - </entity> - - <entity class="Rack" access="FIELD" name="racks"> - <discriminator-value>RACK</discriminator-value> - <attributes> - <id name="id"/> - <basic name="name"> - <column column-definition="text"/> - </basic> - <basic name="capacity"/> - <basic name="powerCapacity"> - <column name="power_capacity_w"/> - </basic> - - <one-to-many name="machines"> - <join-column name="rack_id"/> - </one-to-many> - <transient name="initialState"/> - </attributes> - </entity> - - <entity class="Machine" access="FIELD" name="machines"> - <attributes> - <id name="id"/> - <basic name="position"/> - - <many-to-many name="cpus"> - <join-table name="machine_cpus"> - <join-column name="machine_id"/> - <inverse-join-column name="cpu_id"/> - </join-table> - </many-to-many> - - <many-to-many name="gpus"> - <join-table name="machine_gpus"> - <join-column name="machine_id"/> - <inverse-join-column name="gpu_id"/> - </join-table> - </many-to-many> - <transient name="initialState"/> - </attributes> - </entity> - - <entity class="Cpu" access="FIELD" name="cpus"> - <attributes> - <id name="id"/> - <basic name="manufacturer"> - <column column-definition="text"/> - </basic> - <basic name="family"> - <column column-definition="text"/> - </basic> - <basic name="generation"> - <column column-definition="text"/> - </basic> - <basic name="model"> - <column column-definition="text"/> - </basic> - <basic name="clockRate"> - <column name="clock_rate_mhz"/> - </basic> - <basic name="cores"> - <column name="number_of_cores"/> - </basic> - <basic name="energyConsumption"> - <column name="energy_consumption_w"/> - </basic> - <transient name="initialState"/> - </attributes> - </entity> - - <entity class="Gpu" access="FIELD" name="gpus"> - <attributes> - <id name="id"/> - <basic name="manufacturer"> - <column column-definition="text"/> - </basic> - <basic name="family"> - <column column-definition="text"/> - </basic> - <basic name="generation"> - <column column-definition="text"/> - </basic> - <basic name="model"> - <column column-definition="text"/> - </basic> - <basic name="clockRate"> - <column name="clock_rate_mhz"/> - </basic> - <basic name="cores"> - <column name="number_of_cores"/> - </basic> - <basic name="energyConsumption"> - <column name="energy_consumption_w"/> - </basic> - <transient name="initialState"/> - </attributes> - </entity> - - <entity class="MachineState" access="FIELD" name="machine_states"> - <attributes> - <id name="id"> - <generated-value strategy="IDENTITY"/> - </id> - <basic name="time"> - <column name="tick" column-definition="int(11)"/> - </basic> - <basic name="temperature"> - <column name="temperature_c"/> - </basic> - <basic name="memoryUsage"> - <column name="in_use_memory_mb"/> - </basic> - <basic name="load"> - <column name="load_fraction"/> - </basic> - - <many-to-one name="task"> - <join-column name="task_id"/> - </many-to-one> - <many-to-one name="machine"> - <join-column name="machine_id"/> - </many-to-one> - <many-to-one name="experiment"> - <join-column name="experiment_id"/> - </many-to-one> - </attributes> - </entity> - - <entity class="TaskState" access="FIELD" name="task_states"> - <attributes> - <id name="id"> - <generated-value strategy="IDENTITY"/> - </id> - <basic name="time"> - <column name="tick" column-definition="int(11)"/> - </basic> - <basic name="remaining"> - <column name="flops_left"/> - </basic> - <basic name="cores"> - <column name="cores_used"/> - </basic> - - <many-to-one name="task"> - <join-column name="task_id"/> - </many-to-one> - <many-to-one name="experiment"> - <join-column name="experiment_id"/> - </many-to-one> - </attributes> - </entity> -</entity-mappings> diff --git a/opendc-model-odc/setup/Dockerfile b/opendc-model-odc/setup/Dockerfile deleted file mode 100644 index bfebc044..00000000 --- a/opendc-model-odc/setup/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -# Docker mysql image for the OpenDC simulator project -# This image requires the context to be set to the root directory of the project in order to correctly build. -FROM gradle:alpine -MAINTAINER Fabian Mastenbroek <f.s.mastenbroek@student.tudelft.nl> - -# Set the home directory to our gradle user's home. -ENV HOME=/home/gradle -ENV APP_HOME=$HOME/simulator - -# Copy OpenDC simulator -COPY ./ $APP_HOME - -# Build as root -USER root - -# Set the working directory to the simulator -WORKDIR $APP_HOME - -# Build the application -RUN gradle --no-daemon assemble installDist - -# Fix permissions -RUN chown -R gradle:gradle $APP_HOME - -# Downgrade user -USER gradle - -# Start the Gradle application on run -CMD opendc-model-odc/setup/build/install/setup/bin/setup diff --git a/opendc-model-odc/setup/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaPlatformRunner.kt b/opendc-model-odc/setup/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaPlatformRunner.kt deleted file mode 100644 index ab701259..00000000 --- a/opendc-model-odc/setup/src/main/kotlin/com/atlarge/opendc/model/odc/platform/JpaPlatformRunner.kt +++ /dev/null @@ -1,65 +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 com.atlarge.opendc.model.odc.platform - -import com.atlarge.opendc.omega.OmegaKernel -import mu.KotlinLogging -import java.util.concurrent.Executors -import javax.persistence.Persistence - -val logger = KotlinLogging.logger {} - -/** - * The main entry point of the program. This program polls experiments from a database and runs the - * simulation and reports the results back to the database. - * - * @param args The command line arguments of the program. - */ -fun main(args: Array<String>) { - val properties = HashMap<Any, Any>() - val env = System.getenv() - properties["javax.persistence.jdbc.url"] = env["PERSISTENCE_URL"] ?: "" - properties["javax.persistence.jdbc.user"] = env["PERSISTENCE_USER"] ?: "" - properties["javax.persistence.jdbc.password"] = env["PERSISTENCE_PASSWORD"] ?: "" - val factory = Persistence.createEntityManagerFactory("opendc-simulator", properties) - - val timeout = 30000L - val threads = 4 - val executorService = Executors.newFixedThreadPool(threads) - val experiments = JpaExperimentManager(factory) - val kernel = OmegaKernel - - logger.info { "Waiting for enqueued experiments..." } - while (true) { - experiments.poll()?.let { experiment -> - logger.info { "Found experiment. Submitting for simulation now..." } - executorService.submit { - experiment.use { it.run(kernel, timeout) } - } - } - - Thread.sleep(500) - } -} diff --git a/opendc-model-odc/setup/src/main/resources/META-INF/persistence.xml b/opendc-model-odc/setup/src/main/resources/META-INF/persistence.xml deleted file mode 100644 index a091bdbd..00000000 --- a/opendc-model-odc/setup/src/main/resources/META-INF/persistence.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ 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. - --> - -<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="http://java.sun.com/xml/ns/persistence" - xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" - version="2.0"> - <persistence-unit name="opendc-simulator"> - <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> - <mapping-file>jpa/schema.xml</mapping-file> - <properties> - <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> - <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> - <property name="hibernate.show_sql" value="false"/> - <property name="hibernate.hbm2ddl.auto" value="validate"/> - <property name="hibernate.jdbc.batch_size" value="100"/> - </properties> - </persistence-unit> -</persistence> diff --git a/opendc-stdlib/build.gradle b/opendc-stdlib/build.gradle deleted file mode 100644 index e1ed74ec..00000000 --- a/opendc-stdlib/build.gradle +++ /dev/null @@ -1,43 +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. - */ - -/* Build configuration */ -apply plugin: 'java-library' -apply from: '../gradle/kotlin.gradle' - -/* Project configuration */ -repositories { - jcenter() -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib" - api project(':opendc-core') - implementation "io.github.microutils:kotlin-logging:1.4.6" - - testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_jupiter_version" - testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_jupiter_version" - testImplementation "org.junit.platform:junit-platform-launcher:$junit_platform_version" - testRuntimeOnly "org.slf4j:slf4j-simple:1.7.25" -} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt deleted file mode 100644 index db117917..00000000 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt +++ /dev/null @@ -1,260 +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 com.atlarge.opendc.model.topology - -import com.atlarge.opendc.simulator.Entity -import java.util.concurrent.atomic.AtomicInteger -import com.atlarge.opendc.model.topology.Edge as BaseEdge - -/** - * This module provides a [Topology] implementation backed internally by an adjacency list. - * - * This implementation is best suited for sparse graphs, where an adjacency matrix would take up too much space with - * empty cells. - * - * *Note that this implementation is not synchronized.* - */ -object AdjacencyList { - /** - * Return a [TopologyBuilder] that constructs the topology represents as an adjacency list. - * - * @return A [TopologyBuilder] instance. - */ - fun builder(): TopologyBuilder = AdjacencyListTopologyBuilder() -} - -/** - * A builder for [Topology] instances, which is backed by an adjacency list. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -internal class AdjacencyListTopologyBuilder : TopologyBuilder { - /** - * Build a [Topology] instance from the current state of this builder. - * - * @return The graph built from this builder. - */ - override fun create(): MutableTopology = AdjacencyListTopology() -} - -/** - * A [Topology] whose graph is represented as adjacency list. - */ -internal class AdjacencyListTopology : MutableTopology { - /** - * The identifier for the next node in the graph. - */ - private var nextId: AtomicInteger = AtomicInteger(0) - - /** - * A mapping of nodes to their internal representation with the edges of the nodes. - */ - private var nodes: MutableMap<Entity<*, Topology>, Node> = HashMap() - - // Topology - - /** - * The listeners of this topology. - */ - override val listeners: MutableSet<TopologyListener> = HashSet() - - /** - * A unique identifier of this node within the topology. - */ - override val Entity<*, Topology>.id: Int - get() = nodes[this]!!.id - - /** - * The set of ingoing edges of this node. - */ - override val Entity<*, Topology>.ingoingEdges: MutableSet<BaseEdge<*>> - get() = nodes[this]!!.ingoingEdges - - /** - * The set of outgoing edges of this node. - */ - override val Entity<*, Topology>.outgoingEdges: MutableSet<BaseEdge<*>> - get() = nodes[this]!!.outgoingEdges - - // MutableTopology - - /** - * Create a directed edge between two [Node]s in the topology. - * - * @param from The source of the edge. - * @param to The destination of the edge. - * @param label The label of the edge. - * @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<*, 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) - from.outgoingEdges.add(edge) - to.ingoingEdges.add(edge) - listeners.forEach { it.run { this@AdjacencyListTopology.onEdgeAdded(edge) } } - return edge - } - - // Cloneable - - /** - * Create a copy of the graph. - * - * @return A new [Topology] instance with a copy of the graph. - */ - override fun clone(): Topology { - val copy = AdjacencyListTopology() - copy.nextId = AtomicInteger(nextId.get()) - copy.nodes = HashMap(nodes) - return copy - } - - // Set - - /** - * Returns the size of the collection. - */ - override val size: Int = nodes.size - - /** - * Checks if the specified element is contained in this collection. - */ - 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<*, Topology>>): Boolean = - elements.all { nodes.containsKey(it) } - - /** - * Returns `true` if the collection is empty (contains no elements), `false` otherwise. - */ - override fun isEmpty(): Boolean = nodes.isEmpty() - - // MutableSet - - /** - * Add a node to the graph. - * - * @param element The element to add to this graph. - * @return `true` if the graph has changed, `false` otherwise. - */ - 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 - } - return false - } - - /** - * Add all nodes in the specified collection to the graph. - * - * @param elements The nodes to add to this graph. - * @return `true` if the graph has changed, `false` otherwise. - */ - override fun addAll(elements: Collection<Entity<*, Topology>>): Boolean = elements.any { add(it) } - - /** - * Remove all nodes and their respective edges from the graph. - */ - override fun clear() = nodes.clear() - - /** - * Remove the given node and its edges from the graph. - * - * @param element The element to remove from the graph. - * @return `true` if the graph has changed, `false` otherwise. - */ - override fun remove(element: Entity<*, Topology>): Boolean { - nodes[element]?.ingoingEdges?.forEach { - it.from.outgoingEdges.remove(it) - } - nodes[element]?.outgoingEdges?.forEach { - it.to.ingoingEdges.remove(it) - } - if (nodes.keys.remove(element)) { - listeners.forEach { it.run { this@AdjacencyListTopology.onNodeRemoved(element) } } - return true - } - return false - } - - - /** - * Remove all nodes in the given collection from the graph. - * - * @param elements The elements to remove from the graph. - * @return `true` if the graph has changed, `false` otherwise. - */ - override fun removeAll(elements: Collection<Entity<*, Topology>>): Boolean = elements.any(this::remove) - - /** - * Remove all nodes in the graph, except those in the specified collection. - * - * Take note that this method currently only guarantees a maximum runtime complexity of O(n^2). - * - * @param elements The elements to retain in the graph. - */ - override fun retainAll(elements: Collection<Entity<*, Topology>>): Boolean { - val iterator = nodes.keys.iterator() - var changed = false - while (iterator.hasNext()) { - val entity = iterator.next() - - if (entity !in elements) { - iterator.remove() - changed = true - } - } - return changed - } - - /** - * Return a mutable iterator over the nodes of the graph. - * - * @return A [MutableIterator] over the nodes of the graph. - */ - override fun iterator(): MutableIterator<Entity<*, Topology>> = nodes.keys.iterator() - - /** - * The internal representation of a node within the graph. - */ - internal data class Node(val id: Int) { - val ingoingEdges: MutableSet<BaseEdge<*>> = HashSet() - val outgoingEdges: MutableSet<BaseEdge<*>> = HashSet() - } - - /** - * The internal representation of an edge within the graph. - */ - internal class Edge<out T>(override val label: T, - override val tag: String?, - 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 deleted file mode 100644 index e0b54a28..00000000 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt +++ /dev/null @@ -1,23 +0,0 @@ -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 apply 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-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.kt deleted file mode 100644 index 5e8611a0..00000000 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.kt +++ /dev/null @@ -1,33 +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 com.atlarge.opendc.model.topology - -/** - * A component within a [Topology], which is either a node or an [Edge] representing the relationship between - * entities within a logical topology of a cloud network. - ** - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Component diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt deleted file mode 100644 index 7cf80702..00000000 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt +++ /dev/null @@ -1,65 +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 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 - * should prefer the [Topology] interface. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface MutableTopology : Topology, MutableSet<Entity<*, Topology>> { - /** - * Create a directed, labeled edge between two nodes in the topology. - * - * @param from The source of the edge. - * @param to The destination of the edge. - * @param label The label of the edge. - * @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<*, Topology>, to: Entity<*, Topology>, label: T, tag: String? = null): Edge<T> - - /** - * Create a directed, unlabeled edge between two nodes in the topology. - * - * @param from The source of the edge. - * @param to The destination of the edge. - * @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<*, 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. - * - * @param dest The destination of the edge. - * @return The edge that has been created. - */ - infix fun Entity<*, Topology>.to(dest: Entity<*, Topology>): Edge<Unit> = connect(this, dest) -} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.kt deleted file mode 100644 index 9d78b5eb..00000000 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.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 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 - * and ingoing and outgoing edges of the [Entity] within a [Topology]. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface TopologyContext { - /** - * A unique identifier of an [Entity] within the topology. - */ - val Entity<*, Topology>.id: Int - - /** - * The set of ingoing edges of an [Entity]. - */ - val Entity<*, Topology>.ingoingEdges: Set<Edge<*>> - - /** - * The set of outgoing edges of an [Entity]. - */ - val Entity<*, Topology>.outgoingEdges: Set<Edge<*>> -} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt deleted file mode 100644 index 0b4d43f7..00000000 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt +++ /dev/null @@ -1,63 +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 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 - * mutation of the topology the listener is listening to. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface TopologyListener { - /** - * This method is invoked when an [Entity] is added to the [Topology]. - * - * @param node The entity that has been added to the [Topology]. - */ - 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<*, Topology>) {} - - /** - * This method is invoked when an [Edge] is added to the [Topology]. - * - * @param edge The edge that has been added to the [Topology]. - */ - fun Topology.onEdgeAdded(edge: Edge<*>) {} - - /** - * This method is invoked when an [Edge] is removed from the [Topology]. - * - * @param edge The entity that has been removed from the [Topology]. - */ - fun Topology.onEdgeRemoved(edge: Edge<*>) {} -} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt deleted file mode 100644 index 23720c46..00000000 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt +++ /dev/null @@ -1,41 +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 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`. - * - * @param tag The tag of the edges to get. - * @return An [Iterable] of the specified type `T` with the given tag. - */ -inline fun <reified T> Set<Edge<*>>.origins(tag: String) = filter { it.tag == tag }.map { it.from as T } - -/** - * Filter a [Set] of [Edge]s based on the tag of the edges and return the destination nodes casted to type `T`. - * - * @param tag The tag of the edges to get. - * @return An [Iterable] of the specified type `T` with the given tag. - */ -inline fun <reified T> Set<Edge<*>>.destinations(tag: String) = filter { it.tag == tag }.map { it.to as T } diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/simulator/Helpers.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/simulator/Helpers.kt deleted file mode 100644 index 0f6392ed..00000000 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/simulator/Helpers.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.atlarge.opendc.simulator - -import kotlin.coroutines.experimental.intrinsics.suspendCoroutineOrReturn - -/** - * Try to find the [Context] instance associated with the [Process] in the call chain which has (indirectly) invoked the - * caller of this method. - * - * Note however that this method does not guarantee type-safety as this method allows the user to cast to a context - * with different generic type arguments. - * - * @return The context that has been found or `null` if this method is not called in a simulation context. - */ -suspend fun <S, M> contextOrNull(): Context<S, M>? = suspendCoroutineOrReturn { it.context[Context] } - -/** - * Find the [Context] instance associated with the [Process] in the call chain which has (indirectly) invoked the - * caller of this method. - * - * Note however that this method does not guarantee type-safety as this method allows the user to cast to a context - * with different generic type arguments. - * - * @throws IllegalStateException if the context cannot be found. - * @return The context that has been found. - */ -suspend fun <S, M> context(): Context<S, M> = - contextOrNull() ?: throw IllegalStateException("The suspending call does not have an associated process context") - -/** - * Try to find the untyped [Context] instance associated with the [Process] in the call chain which has (indirectly) - * invoked the caller of this method. - * - * @return The untyped context that has been found or `null` if this method is not called in a simulation context. - */ -suspend fun untypedContextOrNull(): Context<*, *>? = contextOrNull<Any?, Any?>() - -/** - * Find the [Context] instance associated with the [Process] in the call chain which has (indirectly) invoked the - * caller of this method. - * - * @throws IllegalStateException if the context cannot be found. - * @return The untyped context that has been found. - */ -suspend fun untypedContext(): Context<*, *> = context<Any?, Any?>() diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Helpers.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Helpers.kt deleted file mode 100644 index e303133a..00000000 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Helpers.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.atlarge.opendc.simulator.instrumentation - -import kotlinx.coroutines.experimental.Unconfined -import kotlinx.coroutines.experimental.channels.ReceiveChannel -import kotlinx.coroutines.experimental.channels.consumeEach -import kotlinx.coroutines.experimental.channels.produce -import kotlinx.coroutines.experimental.channels.toChannel -import kotlinx.coroutines.experimental.launch -import kotlin.coroutines.experimental.CoroutineContext -import kotlin.coroutines.experimental.coroutineContext - -/** - * Transform each element in the channel into a [ReceiveChannel] of output elements that is then flattened into the - * output stream by emitting elements from the channels as they become available. - * - * @param context The [CoroutineContext] to run the operation in. - * @param transform The function to transform the elements into channels. - * @return The flattened [ReceiveChannel] of merged elements. - */ -fun <E, R> ReceiveChannel<E>.flatMapMerge(context: CoroutineContext = Unconfined, - transform: suspend (E) -> ReceiveChannel<R>): ReceiveChannel<R> = - produce(context) { - val job = launch(Unconfined) { - consumeEach { - launch(coroutineContext) { - transform(it).toChannel(this@produce) - } - } - } - job.join() - } - -/** - * Merge this channel with the other channel into an output stream by emitting elements from the channels as they - * become available. - * - * @param context The [CoroutineContext] to run the operation in. - * @param other The other channel to merge with. - * @return The [ReceiveChannel] of merged elements. - */ -fun <E, E1: E, E2: E> ReceiveChannel<E1>.merge(context: CoroutineContext = Unconfined, - other: ReceiveChannel<E2>): ReceiveChannel<E> = - produce(context) { - val job = launch(Unconfined) { - launch(coroutineContext) { toChannel(this@produce) } - launch(coroutineContext) { other.toChannel(this@produce) } - } - job.join() - } diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Interpolation.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Interpolation.kt deleted file mode 100644 index 5a033ff3..00000000 --- a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Interpolation.kt +++ /dev/null @@ -1,132 +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 com.atlarge.opendc.simulator.instrumentation - -import kotlinx.coroutines.experimental.Unconfined -import kotlinx.coroutines.experimental.channels.ReceiveChannel -import kotlinx.coroutines.experimental.channels.consume -import kotlinx.coroutines.experimental.channels.produce -import kotlin.coroutines.experimental.CoroutineContext - -/** - * Interpolate [n] amount of elements between every two occurrences of elements passing through the channel. - * - * The operation is _intermediate_ and _stateless_. - * This function [consumes][consume] all elements of the original [ReceiveChannel]. - * - * @param context The context of the coroutine. - * @param n The amount of elements to interpolate between the actual elements in the channel. - * @param interpolator A function to interpolate between the two element occurrences. - */ -fun <E> ReceiveChannel<E>.interpolate(n: Int, context: CoroutineContext = Unconfined, - interpolator: (Double, E, E) -> E): ReceiveChannel<E> { - require(n >= 0) { "The amount to interpolate must be non-negative" } - - // If we do not want to interpolate any elements, just return the original channel - if (n == 0) { - return this - } - - return produce(context) { - consume { - val iterator = iterator() - - if (!iterator.hasNext()) - return@produce - - var a = iterator.next() - send(a) - - while (iterator.hasNext()) { - val b = iterator.next() - for (i in 1..n) { - send(interpolator(i.toDouble() / (n + 1), a, b)) - } - send(b) - a = b - } - } - } -} - -/** - * Perform a linear interpolation on the given double values. - * - * @param a The start value - * @param b The end value - * @param f The amount to interpolate which represents the position between the two values as a percentage in [0, 1]. - * @return The interpolated double result between the double values. - */ -fun lerp(a: Double, b: Double, f: Double): Double = a + f * (b - a) - -/** - * Perform a linear interpolation on the given float values. - * - * @param a The start value - * @param b The end value - * @param f The amount to interpolate which represents the position between the two values as a percentage in [0, 1]. - * @return The interpolated float result between the float values. - */ -fun lerp(a: Float, b: Float, f: Float): Float = a + f * (b - a) - -/** - * Perform a linear interpolation on the given integer values. - * - * @param a The start value - * @param b The end value - * @param f The amount to interpolate which represents the position between the two values as a percentage in [0, 1]. - * @return The interpolated integer result between the integer values. - */ -fun lerp(a: Int, b: Int, f: Float): Int = lerp(a.toFloat(), b.toFloat(), f).toInt() - -/** - * Perform a linear interpolation on the given integer values. - * - * @param a The start value - * @param b The end value - * @param f The amount to interpolate which represents the position between the two values as a percentage in [0, 1]. - * @return The interpolated integer result between the integer values. - */ -fun lerp(a: Int, b: Int, f: Double): Int = lerp(a.toDouble(), b.toDouble(), f).toInt() - -/** - * Perform a linear interpolation on the given long values. - * - * @param a The start value - * @param b The end value - * @param f The amount to interpolate which represents the position between the two values as a percentage in [0, 1]. - * @return The interpolated long result between the long values. - */ -fun lerp(a: Long, b: Long, f: Double): Long = lerp(a.toDouble(), b.toDouble(), f).toLong() - -/** - * Perform a linear interpolation on the given long values. - * - * @param a The start value - * @param b The end value - * @param f The amount to interpolate which represents the position between the two values as a percentage in [0, 1]. - * @return The interpolated long result between the long values. - */ -fun lerp(a: Long, b: Long, f: Float): Long = lerp(a.toFloat(), b.toFloat(), f).toLong() diff --git a/settings.gradle b/settings.gradle index b507653b..a7a78f90 100644 --- a/settings.gradle +++ b/settings.gradle @@ -21,11 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -rootProject.name = "opendc-simulator" +rootProject.name = 'opendc-simulator' -include 'opendc-core' -include 'opendc-kernel-omega' -include 'opendc-stdlib' -include 'opendc-model-odc:core' -include 'opendc-model-odc:jpa' -include 'opendc-model-odc:setup' +include 'odcsim-core' +include 'odcsim-engine-omega' |
