From f781a1dba4e1309a2c637d7b47aeef9f55e079b5 Mon Sep 17 00:00:00 2001 From: Georgios Andreadis Date: Thu, 26 Mar 2020 19:58:31 +0100 Subject: Monitor state changes, as well They're now stored in a RLE-fashion. --- .../atlarge/opendc/compute/virt/HypervisorEvent.kt | 11 ++++++ .../atlarge/opendc/compute/virt/HypervisorImage.kt | 1 + .../opendc/compute/virt/driver/SimpleVirtDriver.kt | 11 ++++++ .../atlarge/opendc/experiments/sc20/Sc20Monitor.kt | 40 ++++++++++++++++++---- .../opendc/experiments/sc20/TestExperiment.kt | 12 +++++-- 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 {} } 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 = eventFlow + init { + eventFlow.emit(HypervisorEvent.StateChanged(this, server)) + } + override suspend fun spawn( name: String, image: Image, @@ -238,6 +242,13 @@ class SimpleVirtDriver( this.call = null } + /** + * 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. */ 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>() 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) { 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) { 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() } } -- cgit v1.2.3