diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2018-10-28 12:50:27 +0100 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2019-05-06 18:19:23 +0200 |
| commit | decb8fb5297c7772f5319a47c784d44bf8bdbe9c (patch) | |
| tree | 4151b2ffe1b99a3bfe91a8fd1b7dfeade91a5ec0 | |
| parent | d37a139b357ded9ba048c10ccad320a0d8412f0b (diff) | |
refactor: Introduce initial API design for 2.x
This change introduces the new API design that will be introduced in the
2.x versions of the OpenDC Simulator.
This changes focuses on simplifying simulation primitives provided by
the simulator and introduces a new concept of actors based on the model
designed by the Akka Typed project.
For now, the old simulation models have been removed from the branch,
but will be ported back as this branch is being finalized.
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' |
