summaryrefslogtreecommitdiff
path: root/opendc-simulator/opendc-simulator-resources/src/main
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-06-20 22:56:33 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-06-21 12:19:43 +0200
commitd54ac10449083a490e741d6c54e6f3aa07b71af0 (patch)
tree64632acc289887610c8ccd39b4f0aec9515881ef /opendc-simulator/opendc-simulator-resources/src/main
parent4b9559ce78e1853600c816f8228205ddf405c5a2 (diff)
simulator: Remove concept of resource lifecycle
This change removes the AutoCloseable interface from the SimResourceProvider and removes the concept of a resource lifecycle. Instead, resource providers are now either active (running a resource consumer) or in-active (being idle), which simplifies implementation.
Diffstat (limited to 'opendc-simulator/opendc-simulator-resources/src/main')
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt10
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt24
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCloseableProvider.kt37
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributor.kt4
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt27
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProvider.kt13
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt4
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt6
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt6
-rw-r--r--opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt33
10 files changed, 87 insertions, 77 deletions
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt
index 5fe7d7bb..84217278 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceAggregator.kt
@@ -56,8 +56,6 @@ public abstract class SimAbstractResourceAggregator(
/* SimResourceAggregator */
override fun addInput(input: SimResourceProvider) {
- check(state != SimResourceState.Stopped) { "Aggregator has been stopped" }
-
val consumer = Consumer()
_inputs.add(input)
_inputConsumers.add(consumer)
@@ -70,8 +68,8 @@ public abstract class SimAbstractResourceAggregator(
private val _inputConsumers = mutableListOf<Consumer>()
/* SimResourceProvider */
- override val state: SimResourceState
- get() = _output.state
+ override val isActive: Boolean
+ get() = _output.isActive
override val capacity: Double
get() = _output.capacity
@@ -97,10 +95,6 @@ public abstract class SimAbstractResourceAggregator(
_output.interrupt()
}
- override fun close() {
- _output.close()
- }
-
private val _output = object : SimAbstractResourceProvider(interpreter, parent, initialCapacity = 0.0) {
override fun createLogic(): SimResourceProviderLogic {
return object : SimResourceProviderLogic {
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt
index de26f99e..c1b1450e 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimAbstractResourceProvider.kt
@@ -33,6 +33,12 @@ public abstract class SimAbstractResourceProvider(
initialCapacity: Double
) : SimResourceProvider {
/**
+ * A flag to indicate that the resource provider is active.
+ */
+ public override val isActive: Boolean
+ get() = ctx != null
+
+ /**
* The capacity of the resource.
*/
public override var capacity: Double = initialCapacity
@@ -67,12 +73,6 @@ public abstract class SimAbstractResourceProvider(
private set
/**
- * The state of the resource provider.
- */
- final override var state: SimResourceState = SimResourceState.Pending
- private set
-
- /**
* Construct the [SimResourceProviderLogic] instance for a new consumer.
*/
protected abstract fun createLogic(): SimResourceProviderLogic
@@ -96,21 +96,15 @@ public abstract class SimAbstractResourceProvider(
}
final override fun startConsumer(consumer: SimResourceConsumer) {
- check(state == SimResourceState.Pending) { "Resource is in invalid state" }
+ check(ctx == null) { "Resource is in invalid state" }
val ctx = interpreter.newContext(consumer, createLogic(), parent)
ctx.capacity = capacity
this.ctx = ctx
- this.state = SimResourceState.Active
start(ctx)
}
- override fun close() {
- cancel()
- state = SimResourceState.Stopped
- }
-
final override fun interrupt() {
ctx?.interrupt()
}
@@ -121,10 +115,6 @@ public abstract class SimAbstractResourceProvider(
this.ctx = null
ctx.close()
}
-
- if (state != SimResourceState.Stopped) {
- state = SimResourceState.Pending
- }
}
override fun toString(): String = "SimAbstractResourceProvider[capacity=$capacity]"
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCloseableProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCloseableProvider.kt
new file mode 100644
index 00000000..bce8274b
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceCloseableProvider.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 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 org.opendc.simulator.resources
+
+/**
+ * A [SimResourceProvider] that has a controllable and limited lifetime.
+ *
+ * This interface is used to signal that the resource provider may be closed and not reused after that point.
+ */
+public interface SimResourceCloseableProvider : SimResourceProvider, AutoCloseable {
+ /**
+ * End the lifetime of the resource provider.
+ *
+ * This operation cancels the existing resource consumer and prevents the resource provider from being reused.
+ */
+ public override fun close()
+}
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributor.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributor.kt
index e0333ff9..6bfbfc99 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributor.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributor.kt
@@ -29,10 +29,10 @@ public interface SimResourceDistributor : SimResourceConsumer {
/**
* The output resource providers to which resource consumers can be attached.
*/
- public val outputs: Set<SimResourceProvider>
+ public val outputs: Set<SimResourceCloseableProvider>
/**
* Create a new output for the distributor.
*/
- public fun newOutput(): SimResourceProvider
+ public fun newOutput(): SimResourceCloseableProvider
}
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt
index be9e89fb..f7c5c5d7 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceDistributorMaxMin.kt
@@ -32,7 +32,7 @@ public class SimResourceDistributorMaxMin(
private val interpreter: SimResourceInterpreter,
private val parent: SimResourceSystem? = null
) : SimResourceDistributor {
- override val outputs: Set<SimResourceProvider>
+ override val outputs: Set<SimResourceCloseableProvider>
get() = _outputs
private val _outputs = mutableSetOf<Output>()
@@ -57,7 +57,7 @@ public class SimResourceDistributorMaxMin(
private var totalAllocatedSpeed = 0.0
/* SimResourceDistributor */
- override fun newOutput(): SimResourceProvider {
+ override fun newOutput(): SimResourceCloseableProvider {
val provider = Output(ctx?.capacity ?: 0.0)
_outputs.add(provider)
return provider
@@ -178,7 +178,16 @@ public class SimResourceDistributorMaxMin(
/**
* An internal [SimResourceProvider] implementation for switch outputs.
*/
- private inner class Output(capacity: Double) : SimAbstractResourceProvider(interpreter, parent, capacity), SimResourceProviderLogic, Comparable<Output> {
+ private inner class Output(capacity: Double) :
+ SimAbstractResourceProvider(interpreter, parent, capacity),
+ SimResourceCloseableProvider,
+ SimResourceProviderLogic,
+ Comparable<Output> {
+ /**
+ * A flag to indicate that the output is closed.
+ */
+ private var isClosed: Boolean = false
+
/**
* The current command that is processed by the resource.
*/
@@ -209,6 +218,8 @@ public class SimResourceDistributorMaxMin(
override fun createLogic(): SimResourceProviderLogic = this
override fun start(ctx: SimResourceControllableContext) {
+ check(!isClosed) { "Cannot re-use closed output" }
+
activeOutputs += this
interpreter.batch {
@@ -219,13 +230,9 @@ public class SimResourceDistributorMaxMin(
}
override fun close() {
- val state = state
-
- super.close()
-
- if (state != SimResourceState.Stopped) {
- _outputs.remove(this)
- }
+ isClosed = true
+ cancel()
+ _outputs.remove(this)
}
/* SimResourceProviderLogic */
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProvider.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProvider.kt
index f709ca17..b68b7261 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProvider.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceProvider.kt
@@ -29,11 +29,11 @@ import kotlin.coroutines.resumeWithException
/**
* A [SimResourceProvider] provides a resource that can be consumed by a [SimResourceConsumer].
*/
-public interface SimResourceProvider : AutoCloseable {
+public interface SimResourceProvider {
/**
- * The state of the resource.
+ * A flag to indicate that the resource provider is currently being consumed by a [SimResourceConsumer].
*/
- public val state: SimResourceState
+ public val isActive: Boolean
/**
* The resource capacity available at this instant.
@@ -71,13 +71,6 @@ public interface SimResourceProvider : AutoCloseable {
* Cancel the current resource consumer. If there is no consumer active, this operation will be a no-op.
*/
public fun cancel()
-
- /**
- * End the lifetime of the resource.
- *
- * This operation terminates the existing resource consumer.
- */
- public override fun close()
}
/**
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt
index e224285e..f6e7b22f 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitch.kt
@@ -29,7 +29,7 @@ public interface SimResourceSwitch : AutoCloseable {
/**
* The output resource providers to which resource consumers can be attached.
*/
- public val outputs: Set<SimResourceProvider>
+ public val outputs: Set<SimResourceCloseableProvider>
/**
* The input resources that will be switched between the output providers.
@@ -44,7 +44,7 @@ public interface SimResourceSwitch : AutoCloseable {
/**
* Create a new output on the switch.
*/
- public fun newOutput(): SimResourceProvider
+ public fun newOutput(): SimResourceCloseableProvider
/**
* Add the specified [input] to the switch.
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt
index 2950af80..4ff741ed 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchExclusive.kt
@@ -35,7 +35,7 @@ public class SimResourceSwitchExclusive : SimResourceSwitch {
private var isClosed: Boolean = false
private val _outputs = mutableSetOf<Provider>()
- override val outputs: Set<SimResourceProvider>
+ override val outputs: Set<SimResourceCloseableProvider>
get() = _outputs
private val availableResources = ArrayDeque<SimResourceTransformer>()
@@ -61,7 +61,7 @@ public class SimResourceSwitchExclusive : SimResourceSwitch {
override fun toString(): String = "SimResourceCounters[demand=$demand,actual=$actual,overcommit=$overcommit]"
}
- override fun newOutput(): SimResourceProvider {
+ override fun newOutput(): SimResourceCloseableProvider {
check(!isClosed) { "Switch has been closed" }
check(availableResources.isNotEmpty()) { "No capacity to serve request" }
val forwarder = availableResources.poll()
@@ -101,7 +101,7 @@ public class SimResourceSwitchExclusive : SimResourceSwitch {
_inputs.forEach(SimResourceProvider::cancel)
}
- private inner class Provider(private val forwarder: SimResourceTransformer) : SimResourceProvider by forwarder {
+ private inner class Provider(private val forwarder: SimResourceTransformer) : SimResourceCloseableProvider, SimResourceProvider by forwarder {
override fun close() {
// We explicitly do not close the forwarder here in order to re-use it across output resources.
_outputs -= this
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt
index 684a1b52..50d58798 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceSwitchMaxMin.kt
@@ -33,7 +33,7 @@ public class SimResourceSwitchMaxMin(
/**
* The output resource providers to which resource consumers can be attached.
*/
- override val outputs: Set<SimResourceProvider>
+ override val outputs: Set<SimResourceCloseableProvider>
get() = distributor.outputs
/**
@@ -70,7 +70,7 @@ public class SimResourceSwitchMaxMin(
/**
* Add an output to the switch.
*/
- override fun newOutput(): SimResourceProvider {
+ override fun newOutput(): SimResourceCloseableProvider {
check(!isClosed) { "Switch has been closed" }
return distributor.newOutput()
@@ -88,7 +88,7 @@ public class SimResourceSwitchMaxMin(
override fun close() {
if (!isClosed) {
isClosed = true
- aggregator.close()
+ aggregator.cancel()
}
}
}
diff --git a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt
index fd3d1230..cec27e1c 100644
--- a/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt
+++ b/opendc-simulator/opendc-simulator-resources/src/main/kotlin/org/opendc/simulator/resources/SimResourceTransformer.kt
@@ -33,7 +33,7 @@ import org.opendc.simulator.resources.impl.SimResourceCountersImpl
public class SimResourceTransformer(
private val isCoupled: Boolean = false,
private val transform: (SimResourceContext, SimResourceCommand) -> SimResourceCommand
-) : SimResourceFlow {
+) : SimResourceFlow, AutoCloseable {
/**
* The [SimResourceContext] in which the forwarder runs.
*/
@@ -49,11 +49,8 @@ public class SimResourceTransformer(
*/
private var hasDelegateStarted: Boolean = false
- /**
- * The state of the forwarder.
- */
- override var state: SimResourceState = SimResourceState.Pending
- private set
+ override val isActive: Boolean
+ get() = delegate != null
override val capacity: Double
get() = ctx?.capacity ?: 0.0
@@ -69,9 +66,8 @@ public class SimResourceTransformer(
private val _counters = SimResourceCountersImpl()
override fun startConsumer(consumer: SimResourceConsumer) {
- check(state == SimResourceState.Pending) { "Resource is in invalid state" }
+ check(delegate == null) { "Resource transformer already active" }
- state = SimResourceState.Active
delegate = consumer
// Interrupt the provider to replace the consumer
@@ -86,19 +82,18 @@ public class SimResourceTransformer(
val delegate = delegate
val ctx = ctx
- state = SimResourceState.Pending
-
- if (delegate != null && ctx != null) {
+ if (delegate != null) {
this.delegate = null
- delegate.onEvent(ctx, SimResourceEvent.Exit)
+
+ if (ctx != null) {
+ delegate.onEvent(ctx, SimResourceEvent.Exit)
+ }
}
}
override fun close() {
val ctx = ctx
- state = SimResourceState.Stopped
-
if (ctx != null) {
this.ctx = null
ctx.interrupt()
@@ -114,9 +109,7 @@ public class SimResourceTransformer(
updateCounters(ctx)
- return if (state == SimResourceState.Stopped) {
- SimResourceCommand.Exit
- } else if (delegate != null) {
+ return if (delegate != null) {
val command = transform(ctx, delegate.onNext(ctx))
_work = if (command is SimResourceCommand.Consume) command.work else 0.0
@@ -128,7 +121,7 @@ public class SimResourceTransformer(
delegate.onEvent(ctx, SimResourceEvent.Exit)
- if (isCoupled || state == SimResourceState.Stopped)
+ if (isCoupled)
SimResourceCommand.Exit
else
onNext(ctx)
@@ -184,10 +177,6 @@ public class SimResourceTransformer(
private fun reset() {
delegate = null
hasDelegateStarted = false
-
- if (state != SimResourceState.Stopped) {
- state = SimResourceState.Pending
- }
}
/**