summaryrefslogtreecommitdiff
path: root/odcsim/odcsim-api/src/main/kotlin/com
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2020-02-16 20:30:17 +0100
committerFabian Mastenbroek <mail.fabianm@gmail.com>2020-02-28 14:28:29 +0100
commitb82e573c67f0004945aa18c575268100fb279b56 (patch)
tree7af8e303ea9ab3821e8d8c7c1c7e9b1de058a9e7 /odcsim/odcsim-api/src/main/kotlin/com
parent0c19b32433e2086e72e0d22595f4daa6ef04b64b (diff)
refactor: Change from logical processes to simulation domains
This change moves the simulator terminology from logical processes to simulation domains. This prevents the clash with "processes" that we are trying to simulate. In addition, simulation domains allows us to reduce the amount of boilerplate and instead allows for simulation modelled using standard techniques.
Diffstat (limited to 'odcsim/odcsim-api/src/main/kotlin/com')
-rw-r--r--odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Behavior.kt30
-rw-r--r--odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Channel.kt70
-rw-r--r--odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Channels.kt52
-rw-r--r--odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Domain.kt (renamed from odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/ProcessRef.kt)27
-rw-r--r--odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Port.kt71
-rw-r--r--odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationContext.kt (renamed from odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/ProcessContext.kt)44
-rw-r--r--odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationEngine.kt10
-rw-r--r--odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationEngineProvider.kt7
8 files changed, 39 insertions, 272 deletions
diff --git a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Behavior.kt b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Behavior.kt
deleted file mode 100644
index 1116c447..00000000
--- a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Behavior.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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
-
-/**
- * The behavior of a logical process defines how the process operates within its environments, represented as coroutine.
- */
-public typealias Behavior = suspend (ctx: ProcessContext) -> Unit
diff --git a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Channel.kt b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Channel.kt
deleted file mode 100644
index 10b4908a..00000000
--- a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Channel.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2019 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
-
-/**
- * A unidirectional communication medium using message passing. Processes may send messages over a channel, and
- * another process is able to receive messages sent over a channel it has a reference to (in form of a [ReceivePort]).
- *
- * Channels are represented by their send and receive endpoints at which processes may respectively send and receive
- * messages from this channel.
- *
- * Channels and their respective send and receive references may be shared freely between logical processes in the same
- * simulation.
- */
-public interface Channel<T : Any> : Serializable {
- /**
- * The endpoint of the channel processes may use to send messages to.
- */
- public val send: SendRef<T>
-
- /**
- * The endpoint of the channel processes may receive messages from.
- */
- public val receive: ReceiveRef<T>
-
- /**
- * Obtain the send endpoint of the channel when unpacking the channel. See [send].
- */
- public operator fun component1(): SendRef<T> = send
-
- /**
- * Obtain the receive endpoint of the channel when unpacking the channel. See [receive].
- */
- public operator fun component2(): ReceiveRef<T> = receive
-}
-
-/**
- * An opaque object representing a [Channel] endpoint through which logical processes can send messages over the
- * channel.
- */
-public interface SendRef<in T : Any> : Serializable
-
-/**
- * An opaque object representing the receive endpoint of a [Channel].
- */
-public interface ReceiveRef<out T : Any> : Serializable
diff --git a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Channels.kt b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Channels.kt
deleted file mode 100644
index b15ce3ae..00000000
--- a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Channels.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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
-
-suspend fun <T : Any, U : Any> SendRef<T>.ask(block: (SendRef<U>) -> T): U {
- val ctx = processContext
- val outlet = ctx.connect(this)
- val channel = ctx.open<U>()
- try {
- outlet.send(block(channel.send))
- } finally {
- outlet.close()
- }
-
- val inlet = ctx.listen(channel.receive)
- try {
- return inlet.receive()
- } finally {
- inlet.close()
- }
-}
-
-suspend fun <T : Any> SendRef<T>.sendOnce(msg: T) {
- val outlet = processContext.connect(this)
- try {
- outlet.send(msg)
- } finally {
- outlet.close()
- }
-}
diff --git a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/ProcessRef.kt b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Domain.kt
index 833458e4..c850952c 100644
--- a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/ProcessRef.kt
+++ b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Domain.kt
@@ -24,22 +24,31 @@
package com.atlarge.odcsim
-import java.io.Serializable
+import kotlinx.coroutines.CoroutineScope
/**
- * A reference to a logical process in simulation.
+ * An isolated execution unit that runs concurrently in simulation to the other simulation domains. A domain defines a
+ * logical boundary between processes in simulation.
*/
-public interface ProcessRef : Comparable<ProcessRef>, Serializable {
+public interface Domain : CoroutineScope {
/**
- * The name of the process.
+ * The name of this domain.
*/
public val name: String
/**
- * Compare [other] process ref with this process reference 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.
+ * The parent domain to which the lifecycle of this domain is bound. In case this is a root domain, this refers to
+ * itself.
*/
- override fun compareTo(other: ProcessRef): Int = name.compareTo(other.name)
+ public val parent: Domain
+
+ /**
+ * Construct an anonymous simulation sub-domain that is bound to the lifecycle of this domain.
+ */
+ public fun newDomain(): Domain
+
+ /**
+ * Construct a new simulation sub-domain with the specified [name].
+ */
+ public fun newDomain(name: String): Domain
}
diff --git a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Port.kt b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Port.kt
deleted file mode 100644
index 7c730866..00000000
--- a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/Port.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2019 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 kotlinx.coroutines.selects.SelectClause1
-
-/**
- * A communication endpoint of a specific logical process through which messages pass.
- *
- * Ports are tied to a specific logical process and may not be shared with other processes. Doing so results in
- * undefined behavior and might cause violation of time-consistency between processes.
- */
-public interface Port {
- /**
- * Close this communication endpoint. This informs the process(es) at the other end of the port that the caller
- * will not send or receive messages via this port.
- *
- * This is an idempotent operation – subsequent invocations of this function have no effect and return `false`.
- */
- fun close(): Boolean
-}
-
-/**
- * A [Port] through which a logical process may receive messages from other [SendPort]s.
- */
-public interface ReceivePort<out T : Any> : Port {
- /**
- * Receive a message send to this port or suspend the caller while no messages have been received at this port yet.
- */
- public suspend fun receive(): T
-
- /**
- * Clause for select expression for receiving a message from the channel.
- */
- val onReceive: SelectClause1<T>
-}
-
-/**
- * A [Port] through which logical processes may send messages to a [ReceivePort].
- */
-public interface SendPort<in T : Any> : Port {
- /**
- * Send a message via this port to the process(es) listening at the other end of the port.
- *
- * Messages are send asynchronously to the receivers and do not suspend the caller. This method guarantees
- * exactly-once delivery while respecting time-consistency between owner of the send port and its receivers.
- */
- public fun send(message: T)
-}
diff --git a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/ProcessContext.kt b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationContext.kt
index 30ef4114..c51d1d8b 100644
--- a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/ProcessContext.kt
+++ b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationContext.kt
@@ -27,22 +27,21 @@ package com.atlarge.odcsim
import java.time.Clock
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext
-import kotlinx.coroutines.CoroutineScope
import org.slf4j.Logger
/**
- * Represents the execution context of a logical process in simulation.
+ * Represents the execution context of a simulation domain.
*/
-public interface ProcessContext : CoroutineContext.Element, CoroutineScope {
+public interface SimulationContext : CoroutineContext.Element {
/**
- * Key for [ProcessContext] instance in the coroutine context.
+ * Key for [SimulationContext] instance in the coroutine context.
*/
- companion object Key : CoroutineContext.Key<ProcessContext>
+ companion object Key : CoroutineContext.Key<SimulationContext>
/**
- * The reference to the logical process of this context.
+ * The reference to the current simulation domain.
*/
- public val self: ProcessRef
+ public val domain: Domain
/**
* The clock tracking the simulation time.
@@ -53,37 +52,12 @@ public interface ProcessContext : CoroutineContext.Element, CoroutineScope {
* A logger instance tied to the logical process.
*/
public val log: Logger
-
- /**
- * Spawn an anonymous logical process in the simulation universe with the specified [behavior].
- */
- public fun spawn(behavior: Behavior): ProcessRef
-
- /**
- * Spawn a logical process in the simulation universe with the specified [behavior] and [name].
- */
- public fun spawn(behavior: Behavior, name: String): ProcessRef
-
- /**
- * Open a new communication [Channel] for messages of type [T].
- */
- public fun <T : Any> open(): Channel<T>
-
- /**
- * Create a [SendPort] for sending messages to the specified [send].
- */
- public suspend fun <T : Any> connect(send: SendRef<T>): SendPort<T>
-
- /**
- * Create a [ReceivePort] for listening to the messages sent to the specified [receive] endpoint of a channel.
- */
- public suspend fun <T : Any> listen(receive: ReceiveRef<T>): ReceivePort<T>
}
/**
- * The process context of the current coroutine.
+ * The simulation context of the current coroutine.
*/
@Suppress("WRONG_MODIFIER_TARGET")
-public suspend inline val processContext: ProcessContext
+public suspend inline val simulationContext: SimulationContext
@Suppress("ILLEGAL_SUSPEND_PROPERTY_ACCESS")
- get() = coroutineContext[ProcessContext.Key] ?: throw IllegalStateException("No process context active")
+ get() = coroutineContext[SimulationContext] ?: throw IllegalStateException("No simulation context available")
diff --git a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationEngine.kt b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationEngine.kt
index e35acbf0..db05cb1d 100644
--- a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationEngine.kt
+++ b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationEngine.kt
@@ -37,6 +37,16 @@ public interface SimulationEngine {
public val name: String
/**
+ * Construct an anonymous root simulation domain.
+ */
+ public fun newDomain(): Domain
+
+ /**
+ * Construct a new root simulation domain with the specified [name].
+ */
+ public fun newDomain(name: String): Domain
+
+ /**
* Run the simulation.
*/
public suspend fun run()
diff --git a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationEngineProvider.kt b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationEngineProvider.kt
index 93dda963..a975fa3c 100644
--- a/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationEngineProvider.kt
+++ b/odcsim/odcsim-api/src/main/kotlin/com/atlarge/odcsim/SimulationEngineProvider.kt
@@ -29,10 +29,7 @@ package com.atlarge.odcsim
*/
public interface SimulationEngineProvider {
/**
- * Create an [SimulationEngine] with the given root [Behavior] and the given name.
- *
- * @param root The behavior of the root process.
- * @param name The name of the engine instance.
+ * Construct an [SimulationEngine] with the given [name].
*/
- public operator fun invoke(root: Behavior, name: String): SimulationEngine
+ public operator fun invoke(name: String): SimulationEngine
}