diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2017-08-10 23:32:31 +0200 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2017-08-10 23:32:31 +0200 |
| commit | 295c3c8f0b5bd7218c81e5e659f6ad4800096603 (patch) | |
| tree | f54a7660a779f4bf04091c6b8763a3434ae416f3 | |
| parent | 83cf936bd18e63b98f742e8c3a1df567085aea8e (diff) | |
Start implementation of new architecture
This change introduces a new architecture based on implicit, untyped
connections between nodes in the topology of a cloud network.
This model assumes that entities can only communicate to other entities
directly if they are connected via a channel (edge).
23 files changed, 518 insertions, 81 deletions
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Experiment.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Experiment.kt index 7638b2c8..a4f947c8 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Experiment.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Experiment.kt @@ -27,6 +27,8 @@ package nl.atlarge.opendc.experiment /** * A simulation of multiple simultaneous workloads running on top of a topology. * + * @param id The unique identifier of the experiment. + * @param name The name of the experiment. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -class Experiment {} +data class Experiment(val id: Int, val name: String) diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/ExperimentRunner.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/ExperimentRunner.kt index bb38de99..e53c6e08 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/ExperimentRunner.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/ExperimentRunner.kt @@ -25,8 +25,15 @@ package nl.atlarge.opendc.experiment /** + * An [ExperimentRunner] is responsible for executing an [Experiment]. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ interface ExperimentRunner { + /** + * Run the given [Experiment] using this runner. + * + * @param experiment The experiment to run. + */ + fun run(experiment: Experiment) } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Scheduler.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Scheduler.kt index 713605e4..b2845963 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Scheduler.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Scheduler.kt @@ -25,7 +25,6 @@ package nl.atlarge.opendc.experiment import nl.atlarge.opendc.topology.Entity -import nl.atlarge.opendc.topology.Node /** * A task scheduler that is coupled to an [Entity] in the topology of the cloud network. @@ -36,8 +35,8 @@ interface Scheduler<in E: Entity> { /** * Schedule the given jobs for the given entity. * - * @param node The node in the cloud network topology representing the entity. + * @param entity The entity in the cloud network topology representing the entity. * @param jobs The jobs that have been submitted to the cloud network. */ - fun schedule(node: Node<E>, jobs: Set<Job>) + fun schedule(entity: E, jobs: Set<Job>) } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/User.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/User.kt index d97b980b..8bfba407 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/User.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/User.kt @@ -24,7 +24,7 @@ package nl.atlarge.opendc.experiment -import nl.atlarge.opendc.topology.Node +import nl.atlarge.opendc.topology.Graph /** * A user of a cloud network that provides [Job]s for the simulation. @@ -32,6 +32,9 @@ import nl.atlarge.opendc.topology.Node * <p>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. * + * @param id The unique identifier of the user. + * @param name The name of the user. + * @param view The view of the user on the topology. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -data class User(val id: Int, val name: String, val view: Node<*>) {} +data class User(val id: Int, val name: String, val view: Graph) diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Channel.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Channel.kt new file mode 100644 index 00000000..b33b720d --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Channel.kt @@ -0,0 +1,55 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package nl.atlarge.opendc.experiment.messaging + +import nl.atlarge.opendc.topology.Entity +import nl.atlarge.opendc.topology.Label + +/** + * A direct bi-directional communication channel between two [Entity] instances as seen from one of the entities. + * + * <p>A [Channel] is viewed as an edge that connects two entities in the topology of a cloud network. + * + * @param <E> The type of [Entity] this channel points to. + * @param <T> The type of the label data of this channel. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Channel<out E: Entity, out T>: Pushable, Pullable { + /** + * The [Entity] instance this channel is points to. + */ + val entity: E + + /** + * The label of the channel, possibly containing user-defined information. + */ + val label: Label<T> + + /** + * The channel the message originates from. + */ + val Receivable<Any?>.channel: Channel<E, T> + get() = this@Channel +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Port.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Port.kt new file mode 100644 index 00000000..a2cdba32 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Port.kt @@ -0,0 +1,34 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package nl.atlarge.opendc.experiment.messaging + +import nl.atlarge.opendc.topology.Entity + +/** + * A port connects multiple [Channel]s to an entity in the topology of a cloud network. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Port<out E: Entity, out T>: Iterable<Channel<E, T>>, Pullable, Pushable diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pullable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pullable.kt new file mode 100644 index 00000000..7a756a73 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pullable.kt @@ -0,0 +1,47 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package nl.atlarge.opendc.experiment.messaging + +/** + * A [Pullable] instance allows objects to pull messages from the instance. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Pullable { + /** + * Pull one message from this [Channel] for processing via the given block. + * + * @param block The block to process the message with. + * @return The result of the processed messaged. + */ + fun <T> pull(block: Receivable<Any?>.(Any?) -> T): T + + /** + * Pull one message from this [Channel]. + * + * @return The message that was received from the channel + */ + fun pull(): Any? = pull { it } +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pushable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pushable.kt new file mode 100644 index 00000000..8ec14b6d --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pushable.kt @@ -0,0 +1,18 @@ +package nl.atlarge.opendc.experiment.messaging + +import nl.atlarge.opendc.topology.Entity + +/** + * A [Pushable] instance allows objects to send messages to it. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Pushable { + /** + * Push one message to downstream. + * + * @param msg The message to send downstream. + * @param sender The sender of the message. + */ + fun push(msg: Any?, sender: Entity) +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Receivable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Receivable.kt new file mode 100644 index 00000000..f40ebd30 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Receivable.kt @@ -0,0 +1,44 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package nl.atlarge.opendc.experiment.messaging + +import nl.atlarge.opendc.topology.Entity + +/** + * A message that is received from a [Channel], also containing the metadata of the message. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Receivable<out T> { + /** + * The value of this message. + */ + val value: T + + /** + * The sender of this message. + */ + val sender: Entity +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/AbstractSimulator.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/AbstractSimulator.kt new file mode 100644 index 00000000..109d765e --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/AbstractSimulator.kt @@ -0,0 +1,52 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package nl.atlarge.opendc.experiment.simulator + +import nl.atlarge.opendc.experiment.messaging.Port +import nl.atlarge.opendc.topology.Entity + +/** + * A simulator that simulates a single entity in the topology of a cloud network. + * + * @param ctx The context in which the simulation is run. + * @param <E> The type of entity to simulate. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +abstract class AbstractSimulator<E: Entity>(val ctx: Context<E>): Simulator<E> { + /** + * The [Entity] that is simulated. + */ + val self: E = ctx.entity + + /** + * Create a [Port] of the given type. + * + * @param name The name of the label to create the port for. + * @return The port that has been created or the cached result. + */ + inline fun <reified E: Entity, T> port(name: String): Port<E, T> { + throw NotImplementedError() + } +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Context.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Context.kt new file mode 100644 index 00000000..29ad4dc8 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Context.kt @@ -0,0 +1,67 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package nl.atlarge.opendc.experiment.simulator + +import nl.atlarge.opendc.topology.Entity + +/** + * A context for [Simulator] instance. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Context<E: Entity> { + /** + * The current tick of the experiment. + */ + val tick: Long + + /** + * The [Entity] that is simulated. + */ + val entity: E + + /** + * Update the state of the entity being simulated. + * + * <p>Instead of directly mutating the entity, we create a new instance of the entity to prevent other objects + * referencing the old entity having their data changed. + * + * @param next The next state of the entity. + */ + fun update(next: E) + + /** + * Push the given given tick handler on the stack and change the simulator's behaviour to become the new tick + * handler. + * + * @param block The tick handler to push onto the stack. + */ + fun become(block: Context<E>.() -> Unit) + + /** + * Revert the behaviour of the simulator to the previous handler in the stack. + */ + fun unbecome() +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulates.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulates.kt new file mode 100644 index 00000000..c69c5eff --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulates.kt @@ -0,0 +1,35 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package nl.atlarge.opendc.experiment.simulator + +import nl.atlarge.opendc.topology.Entity +import kotlin.reflect.KClass + +/** + * Classes annotated by this annotation indicates that the annotated class simulates the given entity. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +annotation class Simulates<T: Entity>(val entity: KClass<T>) diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/simulator/Simulator.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulator.kt index 07db1e4c..73747d08 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/simulator/Simulator.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulator.kt @@ -22,33 +22,35 @@ * SOFTWARE. */ -package nl.atlarge.opendc.simulator +package nl.atlarge.opendc.experiment.simulator import nl.atlarge.opendc.topology.Entity /** - * A simulator that simulates a single entity in the topology of a cloud network. + * A simulator that simulates a single [Entity] instance in a cloud network. * - * @param entity The entity to simulate. - * @param ctx The context in which the simulation is run. - * @param <E> The type of entity to simulate. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -abstract class Simulator<out E: Entity>(val entity: E, val ctx: SimulatorContext) { +interface Simulator<E: Entity> { /** - * This method is invoked at least once before a tick. This allows the [Simulator] to setup its state before a tick + * This method is invoked once at the start of the simulation to setup the initial state of the [Simulator]. + */ + fun Context<E>.setUp() {} + + /** + * This method is invoked at least once before a tick. This allows a [Simulator] to setup its state before a tick * event. * * <p>The pre-tick consists of multiple sub-cycles in which all messages which have been sent * in the previous sub-cycle can optionally be processed in the sub-cycle by the receiving [Simulator]. */ - fun preTick() {} + fun Context<E>.preTick() {} /** - * This method is invoked once per tick, which allows the [Simulator] to process events and simulate an entity in a + * This method is invoked once per tick, which allows a [Simulator] to process events to simulate an entity in a * cloud network. */ - fun tick() {} + fun Context<E>.tick() {} /** * This method is invoked at least once per tick. This allows the [Simulator] to do work after a tick. @@ -56,13 +58,10 @@ abstract class Simulator<out E: Entity>(val entity: E, val ctx: SimulatorContext * <p>Like the pre-tick, the post-tick consists of multiple sub-cycles in which all messages which have been sent * in the previous sub-cycle can optionally be processed in the sub-cycle by the receiving [Simulator]. */ - fun postTick() {} + fun Context<E>.postTick() {} /** - * Send the given message to the given [Entity] for processing. - * - * @param destination The entity to send the message to. - * @param message The message to send to the entity. + * This method is invoked once at the end of the simulation to tear down resources of the [Simulator]. */ - fun send(destination: Entity, message: Any?) {} + fun Context<E>.tearDown() {} } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/impl/MachineSimulator.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/impl/MachineSimulator.kt new file mode 100644 index 00000000..4b351753 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/impl/MachineSimulator.kt @@ -0,0 +1,44 @@ +/* + * MIT License + * + * Copyright (c) 2017 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package nl.atlarge.opendc.experiment.simulator.impl + +import nl.atlarge.opendc.experiment.simulator.AbstractSimulator +import nl.atlarge.opendc.experiment.simulator.Context +import nl.atlarge.opendc.experiment.simulator.Simulates +import nl.atlarge.opendc.topology.machine.Cpu +import nl.atlarge.opendc.topology.machine.Machine + +/** + * A simulator for [Machine] entities. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +@Simulates<Machine>(Machine::class) +class MachineSimulator(ctx: Context<Machine>): AbstractSimulator<Machine>(ctx) { + val cpus = port<Cpu, Nothing>("cpu") + + override fun Context<Machine>.tick() { + } +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt index 2d6d4dc8..2f36e6b7 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt @@ -34,6 +34,7 @@ package nl.atlarge.opendc.sampler * <p>An example would be a sampler that tracks [Machine] occupation per time unit, which is achieved by observing the * [Entity]'s event stream and filtering for [JobAssignment] events. * + * @param <T> The data type of result generated by this sampler. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Sampler +interface Sampler<out T> diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt index de5bb0d4..4344e1b5 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt @@ -24,56 +24,72 @@ package nl.atlarge.opendc.topology +import java.util.* + /** - * An edge that represents a connection between exactly two instances of [Node]. - * Instances of [Edge] may be either directed or undirected. + * An undirected edge that represents a connection between exactly two instances of [Entity]. * + * @param from The first incident node. + * @param to The second incident node. + * @param label The label of the edge. + * @param <T> The data type of the label value. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Edge<out T> { +class Edge<out T>(val from: Entity, val to: Entity, val label: Label<T>) { /** - * The label of this edge. + * Return the [Entity] at the opposite end of this [Edge] from the + * specified entity. + * + * Throws [IllegalArgumentException] if <code>entity</code> is + * not incident to this edge. + * + * @param entity The entity to get the opposite of for this edge pair. + * @return The entity at the opposite end of this edge from the specified entity. + * @throws IllegalArgumentException if <code>entity</code> is not incident to this edge. */ - val label: T + fun opposite(entity: Entity): Entity = when (entity) { + from -> to + to -> from + else -> throw IllegalArgumentException() + } /** - * An [Edge] that is directed, having a source and destination [Node]. + * Return a [Pair] representing this edge consisting of both incident nodes. + * Note that the pair is in no particular order. + * + * @return The edge represented as pair of both incident nodes. */ - interface Directed<out T>: Edge<T> { - /** - * The source of the edge. - */ - val from: Node<*> - - /** - * The destination of the edge. - */ - val to: Node<*> - } + fun endpoints(): Pair<Entity, Entity> = Pair(from, to) /** - * An [Edge] that is undirected. + * Determine whether the given object is equal to this instance. + * + * @param other The other object to compare against. + * @return <code>true</code> both edges are equal, <code>false</code> otherwise. */ - interface Undirected<out T>: Edge<T> + override fun equals(other: Any?): Boolean = + if (other is Edge<*>) { + from == other.from && to == other.to || + from == other.to && to == other.from + } else { + false + } /** - * Return the [Node] at the opposite end of this [Edge] from the - * specified node. + * Return the hash code of this edge pair. * - * Throws [IllegalArgumentException] if <code>node</code> is - * not incident to this edge. - * - * @param node The node to get the opposite of for this edge pair. - * @return The node at the opposite end of this edge from the specified node. - * @throws IllegalArgumentException if <code>node</code> is not incident to this edge. + * @return The hash code of this edge pair. */ - fun opposite(node: Node<*>): Node<*> + override fun hashCode(): Int { + return Objects.hash(from, to) + } /** - * Return a [Pair] representing this edge consisting of both incident nodes. - * Note that the pair is in no particular order. + * Return a string representation of this [Edge]. * - * @return The edge represented as pair of both incident nodes. + * @return A string representation of this [Edge]. */ - fun endpoints(): Pair<Node<*>, Node<*>> + override fun toString(): String { + return "Edge($from<->$to)" + } } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt index ef9f3593..c78cba3c 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt @@ -25,13 +25,16 @@ package nl.atlarge.opendc.topology /** - * An entity in a cloud network. + * An entity in the logical topology of a cloud network. + * + * <p>Instances of the [Entity] interface provide direct access to observable state of the entity to other entities in + * the topology connected to it. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ interface Entity { /** - * A unique identifier of this node within the topology represented as a [Int]. + * A unique identifier of this entity within the topology represented as a [Int]. */ val id: Int } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt index e1e361f9..fe1714fc 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt @@ -32,16 +32,16 @@ package nl.atlarge.opendc.topology */ interface Graph { /** - * Add the given [Node] to this graph. + * Return the set of incoming edges of this node. * - * @param node The node to add. + * @return All edges whose destination is this node. */ - fun addNode(node: Node<*>) + fun Entity.incomingEdges(): Set<Edge<*>> /** - * Add the given [Edge] to this graph. + * Return the set of outgoing edges of this node. * - * @param edge The edge to add. + * @return All edges whose source is this node. */ - fun addEdge(edge: Edge<*>) + fun Entity.outgoingEdges(): Set<Edge<*>> } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Node.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/GraphBuilder.kt index cce5990f..a280e88a 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Node.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/GraphBuilder.kt @@ -25,27 +25,29 @@ package nl.atlarge.opendc.topology /** - * A node in the logical topology of a cloud network, representing some [Entity]. + * A builder for [Graph] instances. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Node<out E: Entity> { +interface GraphBuilder { /** - * The [Entity] this node represents. + * Add the given [Entity] to this graph. + * + * @param entity The entity to add. */ - val entity: E + fun add(entity: Entity) /** - * Return the set of incoming edges of this node. + * Add the given [Edge] to this graph. * - * @return All edges whose destination is this node. + * @param edge The edge to add. */ - fun incomingEdges(): Set<Edge<*>> + fun add(edge: Edge<*>) /** - * Return the set of outgoing edges of this node. + * Build a [Graph] instance from the current state of this builder. * - * @return All edges whose source is this node. + * @return The graph built from this builder. */ - fun outgoingEdges(): Set<Edge<*>> + fun build(): Graph } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/simulator/SimulatorContext.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Label.kt index 1ddfbc6a..69174263 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/simulator/SimulatorContext.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Label.kt @@ -22,16 +22,21 @@ * SOFTWARE. */ -package nl.atlarge.opendc.simulator +package nl.atlarge.opendc.topology /** - * The context in which a [Simulator] runs. + * A label for an edge in the topology. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -class SimulatorContext { +interface Label<out T> { /** - * The current tick of the simulation. + * The name of the label. */ - var tick: Long = 0 + val name: String + + /** + * The user-specified data of the label. + */ + val data: T } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Rack.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Rack.kt index cf947ebb..c40b1660 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Rack.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Rack.kt @@ -31,6 +31,7 @@ import nl.atlarge.opendc.topology.Entity * other datacenter computing equipment. * * @param id The unique identifier of this entity. + * @param <T> The type of nodes that are placed in the rack. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -data class Rack(override val id: Int): Entity +data class Rack<T: Entity>(override val id: Int): Entity diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Slot.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Slot.kt index 2556598e..203f7f3b 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Slot.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Slot.kt @@ -24,9 +24,12 @@ package nl.atlarge.opendc.topology.container.rack +import nl.atlarge.opendc.topology.Edge +import nl.atlarge.opendc.topology.Entity + /** * This class represents a slot in a [Rack] of [Machine]s. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -data class Slot(val index: Int) +class Slot<T: Entity>(val rack: Rack<T>, val contents: T, val index: Int): Edge.Directed(rack, contents) diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt index 5fc0086d..cc047136 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt @@ -27,7 +27,7 @@ package nl.atlarge.opendc.topology.power import nl.atlarge.opendc.topology.Entity /** - * An [Entity] which provides power for other entities a cloud network to run. + * A [Entity] which provides power for other entities a cloud network to run. * * @param id The unique identifier of the [Entity]. * @param output The output of the power unit in Watts. |
