From f8a4095d1824df095ea91253f914bc0512646684 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 16 Feb 2018 15:25:19 +0100 Subject: refactor(#18): Provide access to process context in nested calls This change provides a method in the standard library to access the process context in nested suspending function calls. --- .../kotlin/com/atlarge/opendc/simulator/Context.kt | 30 +++++++++++++++++++--- .../kotlin/com/atlarge/opendc/simulator/Process.kt | 2 +- 2 files changed, 27 insertions(+), 5 deletions(-) (limited to 'opendc-core/src/main') 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 index 13170256..24f87eff 100644 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Context.kt +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Context.kt @@ -25,6 +25,7 @@ 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 @@ -33,7 +34,7 @@ import java.util.* * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Context { +interface Context : CoroutineContext.Element { /** * The model of simulation in which the entity exists. */ @@ -50,6 +51,11 @@ interface Context { */ val delta: Duration + /** + * The [Entity] associated with this context. + */ + val self: Entity + /** * The sender of the last received message or `null` in case the process has not received any messages yet. * @@ -68,6 +74,14 @@ interface Context { */ val , S> E.state: S + /** + * 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)) + /** * Interrupt an [Entity] process in simulation. * @@ -75,8 +89,10 @@ interface Context { * 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() + suspend fun Entity<*, *>.interrupt(interrupt: Interrupt) /** * Suspend the [Context] of the [Entity] in simulation for the given duration of simulation time before resuming @@ -159,6 +175,11 @@ interface Context { * @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) + + /** + * This key provides users access to an untyped process context in case the coroutine runs inside a simulation. + */ + companion object Key : CoroutineContext.Key> } /** @@ -185,8 +206,9 @@ interface Envelope { } /** - * An [Interrupt] message is sent to a [Entity] process in order to interrupt its suspended state. + * 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) */ -object Interrupt : Throwable("The entity process has been interrupted by another entity") +open class Interrupt(reason: String) : Throwable(reason) 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 index e8b4d988..f2b8a52b 100644 --- a/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Process.kt +++ b/opendc-core/src/main/kotlin/com/atlarge/opendc/simulator/Process.kt @@ -8,7 +8,7 @@ package com.atlarge.opendc.simulator * @param M The shape of the model in which the process exists. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Process : Entity { +interface Process : Entity { /** * This method is invoked to start the simulation a process. * -- cgit v1.2.3