summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgios Andreadis <info@gandreadis.com>2020-03-26 19:58:31 +0100
committerGeorgios Andreadis <info@gandreadis.com>2020-03-26 19:58:31 +0100
commitf781a1dba4e1309a2c637d7b47aeef9f55e079b5 (patch)
treeb04f2bf5c41bd4a18e091fe163c237d3d94a099d
parent620f194c53d950a37f78577f4aacfd7c0c06bb9a (diff)
Monitor state changes, as well
They're now stored in a RLE-fashion.
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorEvent.kt11
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorImage.kt1
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt11
-rw-r--r--opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20Monitor.kt40
-rw-r--r--opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt12
5 files changed, 67 insertions, 8 deletions
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorEvent.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorEvent.kt
index 5c19b00d..76a73a57 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorEvent.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorEvent.kt
@@ -64,4 +64,15 @@ public sealed class HypervisorEvent {
public val numberOfDeployedImages: Int,
public val hostServer: Server
) : HypervisorEvent()
+
+ /**
+ * This event is emitted when the hypervisor state changes.
+ *
+ * @property driver The driver that emitted the event.
+ * @property server The current server instance.
+ */
+ public data class StateChanged(
+ override val driver: VirtDriver,
+ public val server: Server
+ ) : HypervisorEvent()
}
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorImage.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorImage.kt
index c21b002d..657d5067 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorImage.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorImage.kt
@@ -50,6 +50,7 @@ object HypervisorImage : Image {
try {
suspendCancellableCoroutine<Unit> {}
} finally {
+ driver.onShutOff()
driver.eventFlow.close()
}
}
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt
index 76368080..b6cf3ac8 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt
@@ -87,6 +87,10 @@ class SimpleVirtDriver(
override val events: Flow<HypervisorEvent> = eventFlow
+ init {
+ eventFlow.emit(HypervisorEvent.StateChanged(this, server))
+ }
+
override suspend fun spawn(
name: String,
image: Image,
@@ -239,6 +243,13 @@ class SimpleVirtDriver(
}
/**
+ * To be called on shut-off of the hypervisor.
+ */
+ public fun onShutOff() {
+ eventFlow.emit(HypervisorEvent.StateChanged(this, server))
+ }
+
+ /**
* A request to schedule a virtual CPU on the host cpu.
*/
internal data class CpuRequest(
diff --git a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20Monitor.kt b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20Monitor.kt
index 36da7703..1b3a62b4 100644
--- a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20Monitor.kt
+++ b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20Monitor.kt
@@ -4,6 +4,7 @@ import com.atlarge.odcsim.simulationContext
import com.atlarge.opendc.compute.core.Server
import com.atlarge.opendc.compute.core.ServerState
import com.atlarge.opendc.compute.metal.driver.BareMetalDriver
+import com.atlarge.opendc.compute.virt.driver.VirtDriver
import kotlinx.coroutines.flow.first
import java.io.BufferedWriter
import java.io.Closeable
@@ -13,17 +14,37 @@ class Sc20Monitor(
destination: String
) : Closeable {
private val outputFile = BufferedWriter(FileWriter(destination))
- private var failed: Int = 0
+ private var failedInSlice: Int = 0
+ private val lastServerStates = mutableMapOf<Server, Pair<ServerState, Long>>()
init {
outputFile.write("time,requestedBurst,grantedBurst,numberOfDeployedImages,server,hostUsage,powerDraw,failedVms\n")
}
- suspend fun stateChanged(server: Server) {
+ suspend fun onVmStateChanged(server: Server) {
println("[${simulationContext.clock.millis()}] ${server.uid} ${server.state}")
+
if (server.state == ServerState.ERROR) {
- failed++
+ failedInSlice++
+ }
+ }
+
+ suspend fun serverStateChanged(driver: VirtDriver, server: Server) {
+ if ((server.state == ServerState.SHUTOFF || server.state == ServerState.ERROR) &&
+ lastServerStates.containsKey(server)
+ ) {
+ val duration = simulationContext.clock.millis() - lastServerStates[server]!!.second
+ onSliceFinish(
+ simulationContext.clock.millis(),
+ 0,
+ 0,
+ 0,
+ server,
+ duration
+ )
}
+
+ lastServerStates[server] = Pair(server.state, simulationContext.clock.millis())
}
suspend fun onSliceFinish(
@@ -31,14 +52,21 @@ class Sc20Monitor(
requestedBurst: Long,
grantedBurst: Long,
numberOfDeployedImages: Int,
- hostServer: Server
+ hostServer: Server,
+ duration: Long = 5 * 60 * 1000L
) {
+ lastServerStates.remove(hostServer)
+
// Assume for now that the host is not virtualized and measure the current power draw
val driver = hostServer.services[BareMetalDriver.Key]
val usage = driver.usage.first()
val powerDraw = driver.powerDraw.first()
-
- outputFile.write("$time,$requestedBurst,$grantedBurst,$numberOfDeployedImages,${hostServer.uid},$usage,$powerDraw,$failed")
+ val failed = if (failedInSlice > 0) {
+ failedInSlice.also { failedInSlice = 0 }
+ } else {
+ 0
+ }
+ outputFile.write("$time,$duration,$requestedBurst,$grantedBurst,$numberOfDeployedImages,${hostServer.uid},$usage,$powerDraw,$failed")
outputFile.newLine()
}
diff --git a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt
index 639c3aef..d697cde3 100644
--- a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt
+++ b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt
@@ -146,7 +146,14 @@ fun main(args: Array<String>) {
hypervisor.events
.onEach { event ->
when (event) {
- is HypervisorEvent.SliceFinished -> monitor.onSliceFinish(simulationContext.clock.millis(), event.requestedBurst, event.grantedBurst, event.numberOfDeployedImages, event.hostServer)
+ is HypervisorEvent.StateChanged -> monitor.serverStateChanged(event.driver, event.server)
+ is HypervisorEvent.SliceFinished -> monitor.onSliceFinish(
+ simulationContext.clock.millis(),
+ event.requestedBurst,
+ event.grantedBurst,
+ event.numberOfDeployedImages,
+ event.hostServer
+ )
else -> println(event)
}
}
@@ -175,7 +182,8 @@ fun main(args: Array<String>) {
Flavor(workload.image.cores, workload.image.requiredMemory)
)
// Monitor server events
- server.events.onEach { if (it is ServerEvent.StateChanged) monitor.stateChanged(it.server) }.collect()
+ server.events.onEach { if (it is ServerEvent.StateChanged) monitor.onVmStateChanged(it.server) }
+ .collect()
}
}