From a64ae13a6c5aef435e048b13bb3d7bad449f783b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 14 Feb 2018 12:09:52 +0100 Subject: feat(#11): Create Instrumentation API This commit creates the interfaces for the new Instrumentation API described in issue #11. This interface allows users to plug an instrumentation device into a (live) simulation in order extract measurements from the simulation. --- opendc-core/build.gradle | 1 + .../opendc/simulator/instrumentation/Instrument.kt | 31 ++++++++++++++++++++++ .../atlarge/opendc/simulator/kernel/Simulation.kt | 27 +++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Instrument.kt diff --git a/opendc-core/build.gradle b/opendc-core/build.gradle index 223e73f9..210b8820 100644 --- a/opendc-core/build.gradle +++ b/opendc-core/build.gradle @@ -77,6 +77,7 @@ repositories { dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.2" testCompile "org.junit.jupiter:junit-jupiter-api:5.0.0-RC3" testRuntime "org.junit.jupiter:junit-jupiter-engine:5.0.0-RC3" diff --git a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Instrument.kt b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Instrument.kt new file mode 100644 index 00000000..68f76569 --- /dev/null +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/instrumentation/Instrument.kt @@ -0,0 +1,31 @@ +package com.atlarge.opendc.simulator.instrumentation + +import com.atlarge.opendc.simulator.kernel.Kernel +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.simulator.Context +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 [Kernel.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 = suspend InstrumentScope.() -> 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: SendChannel, Context 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 index bb2ef818..74f1fb36 100644 --- 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 @@ -26,6 +26,9 @@ 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 kotlinx.coroutines.experimental.channels.Channel +import kotlinx.coroutines.experimental.channels.ReceiveChannel /** * A message based discrete event simulation over some model `M`. This interface provides direct control over the @@ -51,6 +54,30 @@ interface Simulation { */ val , S> E.state: S + /** + * Install the given instrumentation device in this kernel to produce a stream of measurements of type + * T. + * + * The [ReceiveChannel] returned by this channel is by default conflated, which means the channel buffers at most + * one measurement, so that the receiver always gets the most recently sent element. + * Back-to-send sent measurements are conflated – only the the most recently sent element is received, while + * previously sent elements are lost. + * + * @param instrument The instrumentation device to install. + * @return A [ReceiveChannel] to which the of measurements produced by the instrument are published. + */ + fun install(instrument: Instrument): ReceiveChannel = install(Channel.CONFLATED, instrument) + + /** + * Install the given instrumentation device in this kernel to produce a stream of measurements of type + * T. + * + * @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 install(capacity: Int = Channel.CONFLATED, instrument: Instrument): ReceiveChannel + /** * 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. -- cgit v1.2.3