diff options
| author | Dante Niewenhuis <d.niewenhuis@hotmail.com> | 2024-05-07 12:33:39 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-07 12:33:39 +0200 |
| commit | ad20465a5df47b49561bb0afbdda5cd65c5da4b8 (patch) | |
| tree | 268f0fde5924b71ca2750dbbbba4cbe24c361f12 /opendc-compute | |
| parent | 7c0691eb6c348d2e49da3ef354b652cf26604905 (diff) | |
Revamped failure models (#228)
Diffstat (limited to 'opendc-compute')
38 files changed, 1607 insertions, 398 deletions
diff --git a/opendc-compute/opendc-compute-api/build.gradle.kts b/opendc-compute/opendc-compute-api/build.gradle.kts index f9b04299..2f855c79 100644 --- a/opendc-compute/opendc-compute-api/build.gradle.kts +++ b/opendc-compute/opendc-compute-api/build.gradle.kts @@ -26,3 +26,6 @@ description = "API interface for the OpenDC Compute service" plugins { `kotlin-library-conventions` } +dependencies { + implementation(project(mapOf("path" to ":opendc-simulator:opendc-simulator-compute"))) +} diff --git a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt index 09cfe6f5..7863f20b 100644 --- a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt +++ b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt @@ -22,6 +22,7 @@ package org.opendc.compute.api +import org.opendc.simulator.compute.workload.SimWorkload import java.util.UUID /** @@ -113,6 +114,11 @@ public interface ComputeClient : AutoCloseable { start: Boolean = true, ): Server + public fun rescheduleServer( + server: Server, + workload: SimWorkload, + ) + /** * Release the resources associated with this client, preventing any further API calls. */ diff --git a/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceLoader.kt b/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceLoader.kt index 685a1fb3..b66aedf9 100644 --- a/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceLoader.kt +++ b/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceLoader.kt @@ -22,11 +22,10 @@ package org.opendc.compute.carbon -import mu.KotlinLogging import org.opendc.trace.Trace import org.opendc.trace.conv.CARBON_INTENSITY_TIMESTAMP import org.opendc.trace.conv.CARBON_INTENSITY_VALUE -import org.opendc.trace.conv.TABLE_CARBON_INTENSITY +import org.opendc.trace.conv.TABLE_CARBON_INTENSITIES import java.io.File import java.lang.ref.SoftReference import java.time.Instant @@ -39,11 +38,6 @@ import java.util.concurrent.ConcurrentHashMap */ public class CarbonTraceLoader { /** - * The logger for this instance. - */ - private val logger = KotlinLogging.logger {} - - /** * The cache of workloads. */ private val cache = ConcurrentHashMap<String, SoftReference<List<CarbonFragment>>>() @@ -54,13 +48,11 @@ public class CarbonTraceLoader { * Read the metadata into a workload. */ private fun parseCarbon(trace: Trace): List<CarbonFragment> { - val reader = checkNotNull(trace.getTable(TABLE_CARBON_INTENSITY)).newReader() + val reader = checkNotNull(trace.getTable(TABLE_CARBON_INTENSITIES)).newReader() val startTimeCol = reader.resolve(CARBON_INTENSITY_TIMESTAMP) val carbonIntensityCol = reader.resolve(CARBON_INTENSITY_VALUE) - val entries = mutableListOf<CarbonFragment>() - try { while (reader.nextRow()) { val startTime = reader.getInstant(startTimeCol)!! diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/FailureModel.kt b/opendc-compute/opendc-compute-failure/build.gradle.kts index 9511017f..d6ec9116 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/FailureModel.kt +++ b/opendc-compute/opendc-compute-failure/build.gradle.kts @@ -20,24 +20,21 @@ * SOFTWARE. */ -package org.opendc.compute.simulator.failure +description = "OpenDC Failure Service implementation" -import org.opendc.compute.service.ComputeService -import java.time.InstantSource -import java.util.random.RandomGenerator -import kotlin.coroutines.CoroutineContext +// Build configuration +plugins { + `kotlin-library-conventions` +} -/** - * Factory interface for constructing [HostFaultInjector] for modeling failures of compute service hosts. - */ -public interface FailureModel { - /** - * Construct a [HostFaultInjector] for the specified [service]. - */ - public fun createInjector( - context: CoroutineContext, - clock: InstantSource, - service: ComputeService, - random: RandomGenerator, - ): HostFaultInjector +dependencies { + api(projects.opendcCompute.opendcComputeApi) + implementation(projects.opendcCommon) + implementation(project(mapOf("path" to ":opendc-trace:opendc-trace-api"))) + implementation(project(mapOf("path" to ":opendc-simulator:opendc-simulator-compute"))) + implementation(project(mapOf("path" to ":opendc-compute:opendc-compute-service"))) + implementation(project(mapOf("path" to ":opendc-compute:opendc-compute-simulator"))) + + api(libs.commons.math3) + implementation(libs.kotlin.logging) } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFault.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt index faf536ad..4134c58a 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFault.kt +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt @@ -20,20 +20,22 @@ * SOFTWARE. */ -package org.opendc.compute.simulator.failure +package org.opendc.compute.failure.hostfault +import org.opendc.compute.service.ComputeService import org.opendc.compute.simulator.SimHost -import java.time.InstantSource /** * Interface responsible for applying the fault to a host. */ -public interface HostFault { +public abstract class HostFault( + private val service: ComputeService, +) { /** * Apply the fault to the specified [victims]. */ - public suspend fun apply( - clock: InstantSource, + public abstract suspend fun apply( victims: List<SimHost>, + faultDuration: Long, ) } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StartStopHostFault.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt index 45545f3b..85138025 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StartStopHostFault.kt +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt @@ -20,39 +20,43 @@ * SOFTWARE. */ -package org.opendc.compute.simulator.failure +package org.opendc.compute.failure.hostfault import kotlinx.coroutines.delay -import org.apache.commons.math3.distribution.RealDistribution +import org.opendc.compute.api.ComputeClient +import org.opendc.compute.service.ComputeService import org.opendc.compute.simulator.SimHost -import java.time.InstantSource -import kotlin.math.roundToLong +import org.opendc.simulator.compute.workload.SimWorkload /** - * A type of [HostFault] where the hosts are stopped and recover after some random amount of time. + * A type of [HostFault] where the hosts are stopped and recover after a given amount of time. */ -public class StartStopHostFault(private val duration: RealDistribution) : HostFault { +public class StartStopHostFault( + private val service: ComputeService, +) : HostFault(service) { override suspend fun apply( - clock: InstantSource, victims: List<SimHost>, + faultDuration: Long, ) { + val client: ComputeClient = service.newClient() + for (host in victims) { - host.fail() - } + val servers = host.instances - val df = (duration.sample() * 1000).roundToLong() // seconds to milliseconds + val snapshots = servers.map { (it.meta["workload"] as SimWorkload).snapshot() } + host.fail() - // Handle long overflow - if (clock.millis() + df <= 0) { - return + for ((server, snapshot) in servers.zip(snapshots)) { + client.rescheduleServer(server, snapshot) + } } - delay(df) + delay(faultDuration) for (host in victims) { host.recover() } } - override fun toString(): String = "StartStopHostFault[$duration]" + override fun toString(): String = "StartStopHostFault" } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/HostFaultInjectorImpl.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt index c75ce528..5f05d96c 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/HostFaultInjectorImpl.kt +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt @@ -20,44 +20,39 @@ * SOFTWARE. */ -package org.opendc.compute.simulator.internal +package org.opendc.compute.failure.models import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.cancel -import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import org.apache.commons.math3.distribution.RealDistribution +import org.opendc.compute.failure.hostfault.HostFault +import org.opendc.compute.failure.hostfault.StartStopHostFault +import org.opendc.compute.failure.victimselector.StochasticVictimSelector +import org.opendc.compute.service.ComputeService import org.opendc.compute.simulator.SimHost -import org.opendc.compute.simulator.failure.HostFault -import org.opendc.compute.simulator.failure.HostFaultInjector -import org.opendc.compute.simulator.failure.VictimSelector import java.time.InstantSource +import java.util.random.RandomGenerator import kotlin.coroutines.CoroutineContext -import kotlin.math.roundToLong /** - * Internal implementation of the [HostFaultInjector] interface. - * - * @param context The scope to run the fault injector in. - * @param clock The [InstantSource] to keep track of simulation time. - * @param hosts The set of hosts to inject faults into. - * @param iat The inter-arrival time distribution of the failures (in hours). - * @param selector The [VictimSelector] to select the host victims. - * @param fault The type of [HostFault] to inject. + * Factory interface for constructing [FailureModel] for modeling failures of compute service hosts. */ -internal class HostFaultInjectorImpl( - private val context: CoroutineContext, - private val clock: InstantSource, - private val hosts: Set<SimHost>, - private val iat: RealDistribution, - private val selector: VictimSelector, - private val fault: HostFault, -) : HostFaultInjector { - /** - * The scope in which the injector runs. - */ - private val scope = CoroutineScope(context + Job()) +public abstract class FailureModel( + context: CoroutineContext, + protected val clock: InstantSource, + protected val service: ComputeService, + protected val random: RandomGenerator, +) : AutoCloseable { + protected val scope: CoroutineScope = CoroutineScope(context + Job()) + + // TODO: could at some point be extended to different types of faults + protected val fault: HostFault = StartStopHostFault(service) + + // TODO: could at some point be extended to different types of victim selectors + protected val victimSelector: StochasticVictimSelector = StochasticVictimSelector(random) + + protected val hosts: Set<SimHost> = service.hosts.map { it as SimHost }.toSet() /** * The [Job] that awaits the nearest fault in the system. @@ -67,7 +62,7 @@ internal class HostFaultInjectorImpl( /** * Start the fault injection into the system. */ - override fun start() { + public fun start() { if (job != null) { return } @@ -79,25 +74,7 @@ internal class HostFaultInjectorImpl( } } - /** - * Converge the injection process. - */ - private suspend fun runInjector() { - while (true) { - // Make sure to convert delay from hours to milliseconds - val d = (iat.sample() * 3.6e6).roundToLong() - - // Handle long overflow - if (clock.millis() + d <= 0) { - return - } - - delay(d) - - val victims = selector.select(hosts) - fault.apply(clock, victims) - } - } + public abstract suspend fun runInjector() /** * Stop the fault injector. diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/SampleBasedFailureModel.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/SampleBasedFailureModel.kt new file mode 100644 index 00000000..3ae66f6f --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/SampleBasedFailureModel.kt @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 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.compute.failure.models + +import kotlinx.coroutines.delay +import org.apache.commons.math3.distribution.RealDistribution +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext +import kotlin.math.max +import kotlin.math.min +import kotlin.math.roundToLong + +/** + * Sample based failure model + * + * @property context + * @property clock + * @property service + * @property random + * @property iatSampler A distribution from which the time until the next fault is sampled in ms + * @property durationSampler A distribution from which the duration of a fault is sampled in s + * @property nohSampler A distribution from which the number of hosts that fault is sampled. + */ +public class SampleBasedFailureModel( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, + private val iatSampler: RealDistribution, + private val durationSampler: RealDistribution, + private val nohSampler: RealDistribution, +) : FailureModel(context, clock, service, random) { + override suspend fun runInjector() { + while (true) { + val iatSample = max(0.0, iatSampler.sample()) + val intervalDuration = (iatSample * 3.6e6).roundToLong() + + // Handle long overflow + if (clock.millis() + intervalDuration <= 0) { + return + } + + delay(intervalDuration) + + val numberOfHosts = min(1.0, max(0.0, nohSampler.sample())) + val victims = victimSelector.select(hosts, numberOfHosts) + + val durationSample = max(0.0, durationSampler.sample()) + val faultDuration = (durationSample * 3.6e6).toLong() + fault.apply(victims, faultDuration) + + break + } + } +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/TraceBasedFailureModel.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/TraceBasedFailureModel.kt new file mode 100644 index 00000000..db8bb1ec --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/TraceBasedFailureModel.kt @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2024 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.compute.failure.models + +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import org.opendc.compute.service.ComputeService +import org.opendc.trace.Trace +import org.opendc.trace.conv.FAILURE_DURATION +import org.opendc.trace.conv.FAILURE_INTENSITY +import org.opendc.trace.conv.FAILURE_INTERVAL +import org.opendc.trace.conv.TABLE_FAILURES +import java.io.File +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +/** + * A definition of a Failure + * + * @property failureInterval The time between this and the previous failure in ms + * @property failureDuration The Duration of the failure in ms + * @property failureIntensity The ratio of hosts affected by the failure + * @constructor Create empty Failure + */ +public data class Failure( + val failureInterval: Long, + val failureDuration: Long, + val failureIntensity: Double, +) { + init { + require(failureInterval >= 0.0) { "A failure cannot start at a negative time" } + require(failureDuration >= 0.0) { "A failure can not have a duration of 0 or less" } + require(failureIntensity > 0.0 && failureIntensity <= 1.0) { "The intensity of a failure has to be in the range (0.0, 1.0]" } + } +} + +/** + * A [FailureModel] based on a provided parquet file + * The file provides a list of [Failure] objects + * + * + * @param context + * @param clock + * @param service + * @param random + * @param pathToTrace The path to the parquet file as a [String] + */ +public class TraceBasedFailureModel( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, + pathToTrace: String, + private val repeat: Boolean = false, +) : FailureModel(context, clock, service, random) { + private val failureList = loadTrace(pathToTrace) + + override suspend fun runInjector() { + do { + for (failure in failureList) { + delay(failure.failureInterval - clock.millis()) + + val victims = victimSelector.select(hosts, failure.failureIntensity) + scope.launch { + fault.apply(victims, failure.failureDuration) + } + } + } while (repeat) + } + + /** + * Load a list [Failure] objects from the provided [pathToFile] + * + * @param pathToFile + */ + private fun loadTrace(pathToFile: String): List<Failure> { + val trace = Trace.open(File(pathToFile), "failure") + + val reader = checkNotNull(trace.getTable(TABLE_FAILURES)).newReader() + + val failureStartTimeCol = reader.resolve(FAILURE_INTERVAL) + val failureDurationCol = reader.resolve(FAILURE_DURATION) + val failureIntensityCol = reader.resolve(FAILURE_INTENSITY) + + val entries = mutableListOf<Failure>() + + try { + while (reader.nextRow()) { + val failureStartTime = reader.getLong(failureStartTimeCol) + val failureDuration = reader.getLong(failureDurationCol) + val failureIntensity = reader.getDouble(failureIntensityCol) + + entries.add(Failure(failureStartTime, failureDuration, failureIntensity)) + } + + return entries + } catch (e: Exception) { + e.printStackTrace() + throw e + } finally { + reader.close() + } + } +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/G5k06.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/G5k06.kt new file mode 100644 index 00000000..da58250d --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/G5k06.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 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.compute.failure.prefab + +import org.apache.commons.math3.distribution.ExponentialDistribution +import org.apache.commons.math3.distribution.GammaDistribution +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.apache.commons.math3.distribution.WeibullDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +/** + * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems" + * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634 + */ +public fun createG5k06Exp( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + ExponentialDistribution(rng, 32.41), + ExponentialDistribution(rng, 7.41), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createG5k06Wbl( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + WeibullDistribution(rng, 0.48, 14.37), + WeibullDistribution(rng, 0.35, 0.47), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createG5k06LogN( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + LogNormalDistribution(rng, 1.51, 2.42), + LogNormalDistribution(rng, -2.0, 2.2), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createG5k06Gam( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + GammaDistribution(rng, 0.34, 94.35), + GammaDistribution(rng, 0.19, 39.92), + UniformRealDistribution(0.0, 1.0), + ) +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Lanl05.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Lanl05.kt new file mode 100644 index 00000000..3e722630 --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Lanl05.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 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.compute.failure.prefab + +import org.apache.commons.math3.distribution.ExponentialDistribution +import org.apache.commons.math3.distribution.GammaDistribution +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.apache.commons.math3.distribution.WeibullDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +/** + * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems" + * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634 + */ +public fun createLanl05Exp( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + ExponentialDistribution(rng, 1779.99), + ExponentialDistribution(rng, 5.92), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createLanl05Wbl( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + WeibullDistribution(rng, 0.48, 816.60), + WeibullDistribution(rng, 0.58, 2.18), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createLanl05LogN( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + LogNormalDistribution(rng, 5.56, 2.39), + LogNormalDistribution(rng, 0.05, 1.42), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createLanl05Gam( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + GammaDistribution(rng, 0.35, 5102.71), + GammaDistribution(rng, 0.38, 15.44), + UniformRealDistribution(0.0, 1.0), + ) +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Ldns04.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Ldns04.kt new file mode 100644 index 00000000..4a8b3c0f --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Ldns04.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 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.compute.failure.prefab + +import org.apache.commons.math3.distribution.ExponentialDistribution +import org.apache.commons.math3.distribution.GammaDistribution +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.apache.commons.math3.distribution.WeibullDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +/** + * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems" + * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634 + */ +public fun createLdns04Exp( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + ExponentialDistribution(rng, 141.06), + ExponentialDistribution(rng, 8.61), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createLdns04Wbl( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + WeibullDistribution(rng, 0.51, 79.30), + WeibullDistribution(rng, 0.63, 5.62), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createLdns04LogN( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + LogNormalDistribution(rng, 3.25, 2.33), + LogNormalDistribution(rng, 0.91, 1.64), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createLdns04Gam( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + GammaDistribution(rng, 0.39, 362.43), + GammaDistribution(rng, 0.51, 16.87), + UniformRealDistribution(0.0, 1.0), + ) +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Microsoft99.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Microsoft99.kt new file mode 100644 index 00000000..725f6622 --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Microsoft99.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 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.compute.failure.prefab + +import org.apache.commons.math3.distribution.ExponentialDistribution +import org.apache.commons.math3.distribution.GammaDistribution +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.apache.commons.math3.distribution.WeibullDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +/** + * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems" + * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634 + */ +public fun createMicrosoft99Exp( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + ExponentialDistribution(rng, 67.01), + ExponentialDistribution(rng, 16.49), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createMicrosoft99Wbl( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + WeibullDistribution(rng, 0.55, 35.30), + WeibullDistribution(rng, 0.60, 9.34), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createMicrosoft99LogN( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + LogNormalDistribution(rng, 2.62, 1.84), + LogNormalDistribution(rng, 1.42, 1.54), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createMicrosoft99Gam( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + GammaDistribution(rng, 0.41, 162.19), + GammaDistribution(rng, 0.46, 35.52), + UniformRealDistribution(0.0, 1.0), + ) +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Nd07cpu.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Nd07cpu.kt new file mode 100644 index 00000000..100a3a8d --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Nd07cpu.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 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.compute.failure.prefab + +import org.apache.commons.math3.distribution.ExponentialDistribution +import org.apache.commons.math3.distribution.GammaDistribution +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.apache.commons.math3.distribution.WeibullDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +/** + * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems" + * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634 + */ +public fun createNd07cpuExp( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + ExponentialDistribution(rng, 13.73), + ExponentialDistribution(rng, 4.25), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createNd07cpuWbl( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + WeibullDistribution(rng, 0.45, 4.16), + WeibullDistribution(rng, 0.51, 0.74), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createNd07cpuLogN( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + LogNormalDistribution(rng, 0.30, 2.20), + LogNormalDistribution(rng, -1.02, 1.27), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createNd07cpuGam( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + GammaDistribution(rng, 0.30, 46.16), + GammaDistribution(rng, 0.28, 15.07), + UniformRealDistribution(0.0, 1.0), + ) +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Overnet03.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Overnet03.kt new file mode 100644 index 00000000..4f5e3f84 --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Overnet03.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 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.compute.failure.prefab + +import org.apache.commons.math3.distribution.ExponentialDistribution +import org.apache.commons.math3.distribution.GammaDistribution +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.apache.commons.math3.distribution.WeibullDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +/** + * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems" + * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634 + */ +public fun createOvernet03Exp( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + ExponentialDistribution(rng, 2.29), + ExponentialDistribution(rng, 12.00), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createOvernet03Wbl( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + WeibullDistribution(rng, 0.85, 2.04), + WeibullDistribution(rng, 0.44, 2.98), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createOvernet03LogN( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + LogNormalDistribution(rng, 0.19, 0.98), + LogNormalDistribution(rng, 0.08, 1.80), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createOvernet03Gam( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + GammaDistribution(rng, 0.91, 2.53), + GammaDistribution(rng, 0.29, 41.64), + UniformRealDistribution(0.0, 1.0), + ) +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Pl05.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Pl05.kt new file mode 100644 index 00000000..3e1f1b58 --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Pl05.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 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.compute.failure.prefab + +import org.apache.commons.math3.distribution.ExponentialDistribution +import org.apache.commons.math3.distribution.GammaDistribution +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.apache.commons.math3.distribution.WeibullDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +/** + * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems" + * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634 + */ +public fun createPl05Exp( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + ExponentialDistribution(rng, 159.49), + ExponentialDistribution(rng, 49.61), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createPl05Wbl( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + WeibullDistribution(rng, 0.33, 19.35), + WeibullDistribution(rng, 0.36, 5.59), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createPl05LogN( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + LogNormalDistribution(rng, 1.44, 2.86), + LogNormalDistribution(rng, 0.40, 2.45), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createPl05Gam( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + GammaDistribution(rng, 0.20, 788.03), + GammaDistribution(rng, 0.21, 237.65), + UniformRealDistribution(0.0, 1.0), + ) +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/PrefabFailureModelFactory.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/PrefabFailureModelFactory.kt new file mode 100644 index 00000000..477f3ac4 --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/PrefabFailureModelFactory.kt @@ -0,0 +1,140 @@ +/* + * 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. + */ + +@file:JvmName("FailureModels") + +package org.opendc.compute.failure.prefab + +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +public enum class FailurePrefab { + G5k06Exp, + G5k06Wbl, + G5k06LogN, + G5k06Gam, + Lanl05Exp, + Lanl05Wbl, + Lanl05LogN, + Lanl05Gam, + Ldns04Exp, + Ldns04Wbl, + Ldns04LogN, + Ldns04Gam, + Microsoft99Exp, + Microsoft99Wbl, + Microsoft99LogN, + Microsoft99Gam, + Nd07cpuExp, + Nd07cpuWbl, + Nd07cpuLogN, + Nd07cpuGam, + Overnet03Exp, + Overnet03Wbl, + Overnet03LogN, + Overnet03Gam, + Pl05Exp, + Pl05Wbl, + Pl05LogN, + Pl05Gam, + Skype06Exp, + Skype06Wbl, + Skype06LogN, + Skype06Gam, + Websites02Exp, + Websites02Wbl, + Websites02LogN, + Websites02Gam, +} + +/** + * Get a [SampleBasedFailureModel] based on the provided prefab. + * All Failure models are based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems" + * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634 + * + * + * @param context + * @param clock + * @param service + * @param random + * @param prefab The name of the failure model prefab + * @return + */ +public fun createFailureModelPrefab( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, + prefab: FailurePrefab, +): SampleBasedFailureModel { + when (prefab) { + FailurePrefab.G5k06Exp -> return createG5k06Exp(context, clock, service, random) + FailurePrefab.G5k06Wbl -> return createG5k06Wbl(context, clock, service, random) + FailurePrefab.G5k06LogN -> return createG5k06LogN(context, clock, service, random) + FailurePrefab.G5k06Gam -> return createG5k06Gam(context, clock, service, random) + + FailurePrefab.Lanl05Exp -> return createLanl05Exp(context, clock, service, random) + FailurePrefab.Lanl05Wbl -> return createLanl05Wbl(context, clock, service, random) + FailurePrefab.Lanl05LogN -> return createLanl05LogN(context, clock, service, random) + FailurePrefab.Lanl05Gam -> return createLanl05Gam(context, clock, service, random) + + FailurePrefab.Ldns04Exp -> return createLdns04Exp(context, clock, service, random) + FailurePrefab.Ldns04Wbl -> return createLdns04Wbl(context, clock, service, random) + FailurePrefab.Ldns04LogN -> return createLdns04LogN(context, clock, service, random) + FailurePrefab.Ldns04Gam -> return createLdns04Gam(context, clock, service, random) + + FailurePrefab.Microsoft99Exp -> return createMicrosoft99Exp(context, clock, service, random) + FailurePrefab.Microsoft99Wbl -> return createMicrosoft99Wbl(context, clock, service, random) + FailurePrefab.Microsoft99LogN -> return createMicrosoft99LogN(context, clock, service, random) + FailurePrefab.Microsoft99Gam -> return createMicrosoft99Gam(context, clock, service, random) + + FailurePrefab.Nd07cpuExp -> return createNd07cpuExp(context, clock, service, random) + FailurePrefab.Nd07cpuWbl -> return createNd07cpuWbl(context, clock, service, random) + FailurePrefab.Nd07cpuLogN -> return createNd07cpuLogN(context, clock, service, random) + FailurePrefab.Nd07cpuGam -> return createNd07cpuGam(context, clock, service, random) + + FailurePrefab.Overnet03Exp -> return createOvernet03Exp(context, clock, service, random) + FailurePrefab.Overnet03Wbl -> return createOvernet03Wbl(context, clock, service, random) + FailurePrefab.Overnet03LogN -> return createOvernet03LogN(context, clock, service, random) + FailurePrefab.Overnet03Gam -> return createOvernet03Gam(context, clock, service, random) + + FailurePrefab.Pl05Exp -> return createPl05Exp(context, clock, service, random) + FailurePrefab.Pl05Wbl -> return createPl05Wbl(context, clock, service, random) + FailurePrefab.Pl05LogN -> return createPl05LogN(context, clock, service, random) + FailurePrefab.Pl05Gam -> return createPl05Gam(context, clock, service, random) + + FailurePrefab.Skype06Exp -> return createSkype06Exp(context, clock, service, random) + FailurePrefab.Skype06Wbl -> return createSkype06Wbl(context, clock, service, random) + FailurePrefab.Skype06LogN -> return createSkype06LogN(context, clock, service, random) + FailurePrefab.Skype06Gam -> return createSkype06Gam(context, clock, service, random) + + FailurePrefab.Websites02Exp -> return createWebsites02Exp(context, clock, service, random) + FailurePrefab.Websites02Wbl -> return createWebsites02Wbl(context, clock, service, random) + FailurePrefab.Websites02LogN -> return createWebsites02LogN(context, clock, service, random) + FailurePrefab.Websites02Gam -> return createWebsites02Gam(context, clock, service, random) + + else -> error("Unknown failure prefab: $prefab") + } +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Skype06.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Skype06.kt new file mode 100644 index 00000000..7495bf66 --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Skype06.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 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.compute.failure.prefab + +import org.apache.commons.math3.distribution.ExponentialDistribution +import org.apache.commons.math3.distribution.GammaDistribution +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.apache.commons.math3.distribution.WeibullDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +/** + * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems" + * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634 + */ +public fun createSkype06Exp( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + ExponentialDistribution(rng, 16.27), + ExponentialDistribution(rng, 14.31), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createSkype06Wbl( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + WeibullDistribution(rng, 0.64, 10.86), + WeibullDistribution(rng, 0.63, 9.48), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createSkype06LogN( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + LogNormalDistribution(rng, 1.60, 1.57), + LogNormalDistribution(rng, 1.40, 1.73), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createSkype06Gam( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + GammaDistribution(rng, 0.53, 30.79), + GammaDistribution(rng, 0.50, 28.53), + UniformRealDistribution(0.0, 1.0), + ) +} diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Websites02.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Websites02.kt new file mode 100644 index 00000000..77bb0d64 --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Websites02.kt @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024 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.compute.failure.prefab + +import org.apache.commons.math3.distribution.ExponentialDistribution +import org.apache.commons.math3.distribution.GammaDistribution +import org.apache.commons.math3.distribution.LogNormalDistribution +import org.apache.commons.math3.distribution.UniformRealDistribution +import org.apache.commons.math3.distribution.WeibullDistribution +import org.apache.commons.math3.random.Well19937c +import org.opendc.compute.failure.models.SampleBasedFailureModel +import org.opendc.compute.service.ComputeService +import java.time.InstantSource +import java.util.random.RandomGenerator +import kotlin.coroutines.CoroutineContext + +/** + * Failure models based on values taken from "The Failure Trace Archive: Enabling the comparison of failure measurements and models of distributed systems" + * Which can be found at https://www-sciencedirect-com.vu-nl.idm.oclc.org/science/article/pii/S0743731513000634 + */ +public fun createWebsites02Exp( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + ExponentialDistribution(rng, 11.85), + ExponentialDistribution(rng, 1.18), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createWebsites02Wbl( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + WeibullDistribution(rng, 0.46, 3.68), + WeibullDistribution(rng, 0.65, 0.61), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createWebsites02LogN( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + LogNormalDistribution(rng, 0.23, 2.02), + LogNormalDistribution(rng, -1.12, 1.13), + UniformRealDistribution(0.0, 1.0), + ) +} + +public fun createWebsites02Gam( + context: CoroutineContext, + clock: InstantSource, + service: ComputeService, + random: RandomGenerator, +): SampleBasedFailureModel { + val rng = Well19937c(random.nextLong()) + + return SampleBasedFailureModel( + context, + clock, + service, + random, + GammaDistribution(rng, 0.31, 38.67), + GammaDistribution(rng, 0.50, 2.37), + UniformRealDistribution(0.0, 1.0), + ) +} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StochasticVictimSelector.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt index 93463cdb..fef60eb3 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/StochasticVictimSelector.kt +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt @@ -20,28 +20,32 @@ * SOFTWARE. */ -package org.opendc.compute.simulator.failure +package org.opendc.compute.failure.victimselector -import org.apache.commons.math3.distribution.RealDistribution import org.opendc.compute.simulator.SimHost -import java.util.ArrayList import java.util.SplittableRandom import java.util.random.RandomGenerator -import kotlin.math.roundToInt +import kotlin.math.max +import kotlin.math.min /** * A [VictimSelector] that stochastically selects a set of hosts to be failed. */ public class StochasticVictimSelector( - private val size: RealDistribution, private val random: RandomGenerator = SplittableRandom(0), ) : VictimSelector { - override fun select(hosts: Set<SimHost>): List<SimHost> { - val n = size.sample().roundToInt() - val result = ArrayList<SimHost>(n) + override fun select(numberOfHosts: Int): List<SimHost> { + error("select with only int cannot be used in this type of VictimSelector") + } + + override fun select( + hosts: Set<SimHost>, + numberOfHosts: Int, + ): List<SimHost> { + val result = ArrayList<SimHost>(numberOfHosts) val random = random - var samplesNeeded = n + var samplesNeeded = numberOfHosts var remainingHosts = hosts.size val iterator = hosts.iterator() @@ -59,5 +63,20 @@ public class StochasticVictimSelector( return result } - override fun toString(): String = "StochasticVictimSelector[$size]" + override fun select(failureIntensity: Double): List<SimHost> { + error("select with only int cannot be used in this type of VictimSelector") + } + + override fun select( + hosts: Set<SimHost>, + failureIntensity: Double, + ): List<SimHost> { + // clamp value between 0.0 and 1.0 + val intensity = min(1.0, max(0.0, failureIntensity)) + val numberOfHosts = (hosts.size * intensity).toInt() + + return hosts.asSequence().shuffled().take(numberOfHosts).toList() + } + + override fun toString(): String = "StochasticVictimSelector" } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/VictimSelector.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt index b5610284..955cbced 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/VictimSelector.kt +++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.opendc.compute.simulator.failure +package org.opendc.compute.failure.victimselector import org.opendc.compute.simulator.SimHost @@ -31,5 +31,17 @@ public interface VictimSelector { /** * Select the hosts from [hosts] where a fault will be injected. */ - public fun select(hosts: Set<SimHost>): List<SimHost> + public fun select( + hosts: Set<SimHost>, + numberOfHosts: Int, + ): List<SimHost> + + public fun select(numberOfHosts: Int): List<SimHost> + + public fun select(failureIntensity: Double): List<SimHost> + + public fun select( + hosts: Set<SimHost>, + failureIntensity: Double, + ): List<SimHost> } diff --git a/opendc-compute/opendc-compute-failure/src/test/resources/log4j2.xml b/opendc-compute/opendc-compute-failure/src/test/resources/log4j2.xml new file mode 100644 index 00000000..0dfb75f2 --- /dev/null +++ b/opendc-compute/opendc-compute-failure/src/test/resources/log4j2.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> + +<Configuration status="WARN" packages="org.apache.logging.log4j.core"> + <Appenders> + <Console name="Console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%highlight{%-5level}] %logger{36} - %msg%n" disableAnsi="false"/> + </Console> + </Appenders> + <Loggers> + <Logger name="org.opendc" level="trace" additivity="false"> + <AppenderRef ref="Console"/> + </Logger> + <Root level="info"> + <AppenderRef ref="Console"/> + </Root> + </Loggers> +</Configuration> diff --git a/opendc-compute/opendc-compute-service/build.gradle.kts b/opendc-compute/opendc-compute-service/build.gradle.kts index 0efdb05f..cd25e05c 100644 --- a/opendc-compute/opendc-compute-service/build.gradle.kts +++ b/opendc-compute/opendc-compute-service/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { api(projects.opendcCompute.opendcComputeApi) implementation(projects.opendcCommon) implementation(libs.kotlin.logging) + implementation(project(mapOf("path" to ":opendc-simulator:opendc-simulator-compute"))) testImplementation(projects.opendcSimulator.opendcSimulatorCore) testImplementation(libs.log4j.slf4j) diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java index 167b13c7..a7e9f509 100644 --- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java +++ b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java @@ -52,6 +52,7 @@ import org.opendc.compute.service.driver.HostModel; import org.opendc.compute.service.driver.HostState; import org.opendc.compute.service.scheduler.ComputeScheduler; import org.opendc.compute.service.telemetry.SchedulerStats; +import org.opendc.simulator.compute.workload.SimWorkload; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -161,7 +162,9 @@ public final class ComputeService implements AutoCloseable { serviceServer.setState(newState); - if (newState == ServerState.TERMINATED || newState == ServerState.DELETED) { + if (newState == ServerState.TERMINATED + || newState == ServerState.DELETED + || newState == ServerState.ERROR) { LOGGER.info("Server {} {} {} finished", server.getUid(), server.getName(), server.getFlavor()); if (activeServers.remove(server) != null) { @@ -353,6 +356,8 @@ public final class ComputeService implements AutoCloseable { * Run a single scheduling iteration. */ private void doSchedule() { + // reorder tasks + while (!queue.isEmpty()) { SchedulingRequest request = queue.peek(); @@ -363,6 +368,9 @@ public final class ComputeService implements AutoCloseable { } final ServiceServer server = request.server; + // Check if all dependencies are met + // otherwise continue + final ServiceFlavor flavor = server.getFlavor(); final HostView hv = scheduler.select(request.server); @@ -582,6 +590,20 @@ public final class ComputeService implements AutoCloseable { public String toString() { return "ComputeService.Client"; } + + @Nullable + @Override + public void rescheduleServer(@NotNull Server server, @NotNull SimWorkload workload) { + ServiceServer internalServer = (ServiceServer) findServer(server.getUid()); + Host from = service.lookupHost(internalServer); + + from.delete(internalServer); + + internalServer.host = null; + + internalServer.setWorkload(workload); + internalServer.start(); + } } /** diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceServer.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceServer.java index 265feac0..e363faf2 100644 --- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceServer.java +++ b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceServer.java @@ -25,6 +25,7 @@ package org.opendc.compute.service; import java.time.Instant; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -46,11 +47,12 @@ public final class ServiceServer implements Server { private final ComputeService service; private final UUID uid; + private final String name; private final ServiceFlavor flavor; private final ServiceImage image; private final Map<String, String> labels; - private final Map<String, ?> meta; + private Map<String, ?> meta; private final List<ServerWatcher> watchers = new ArrayList<>(); private ServerState state = ServerState.TERMINATED; @@ -111,6 +113,13 @@ public final class ServiceServer implements Server { return Collections.unmodifiableMap(meta); } + public void setWorkload(Object _workload) { + Map<String, Object> new_meta = new HashMap<String, Object>(); + new_meta.put("workload", _workload); + + meta = new_meta; + } + @NotNull @Override public ServerState getState() { diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt index cdcd1af0..41118386 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt @@ -101,6 +101,7 @@ public class FilterScheduler( filteredHosts } + // fixme: currently finding no matching hosts can result in an error return when (val maxSize = min(subsetSize, subset.size)) { 0 -> null 1 -> subset[0] diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt index 23590c13..dd707f60 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt @@ -34,7 +34,8 @@ public class ComputeFilter : HostFilter { host: HostView, server: Server, ): Boolean { - return host.host.state == HostState.UP + val result = host.host.state == HostState.UP + return result } override fun toString(): String = "ComputeFilter" diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt index 4792a7a0..d8c3d540 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt @@ -35,19 +35,21 @@ public class RamFilter(private val allocationRatio: Double) : HostFilter { host: HostView, server: Server, ): Boolean { - val requested = server.flavor.memorySize - val available = host.availableMemory - val total = host.host.model.memoryCapacity + val requestedMemory = server.flavor.memorySize + val availableMemory = host.availableMemory + val memoryCapacity = host.host.model.memoryCapacity // Do not allow an instance to overcommit against itself, only against // other instances. - if (requested > total) { + if (requestedMemory > memoryCapacity) { return false } - val limit = total * allocationRatio - val used = total - available + val limit = memoryCapacity * allocationRatio + val used = memoryCapacity - availableMemory val usable = limit - used - return usable >= requested + + val result = usable >= requestedMemory + return result } } diff --git a/opendc-compute/opendc-compute-simulator/build.gradle.kts b/opendc-compute/opendc-compute-simulator/build.gradle.kts index 0cddd296..20ceb93e 100644 --- a/opendc-compute/opendc-compute-simulator/build.gradle.kts +++ b/opendc-compute/opendc-compute-simulator/build.gradle.kts @@ -39,6 +39,8 @@ dependencies { implementation(project(mapOf("path" to ":opendc-compute:opendc-compute-telemetry"))) implementation(project(mapOf("path" to ":opendc-compute:opendc-compute-carbon"))) + implementation(project(mapOf("path" to ":opendc-trace:opendc-trace-api"))) + testImplementation(projects.opendcSimulator.opendcSimulatorCore) testRuntimeOnly(libs.slf4j.simple) } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 84799123..00f2acb3 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -190,6 +190,9 @@ public class SimHost( override fun delete(server: Server) { val guest = guests[server] ?: return guest.delete() + + guests.remove(server) + localGuests.remove(guest) } override fun addListener(listener: HostListener) { diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/FailureModelFactory.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/checkpoints/CheckpointModel.kt index 406665c7..781c2025 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/FailureModelFactory.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/checkpoints/CheckpointModel.kt @@ -20,22 +20,9 @@ * SOFTWARE. */ -package org.opendc.compute.simulator.failure +package org.opendc.compute.simulator.checkpoints -import org.opendc.compute.simulator.failure.models.Grid5000 -import java.time.Duration -import kotlin.math.roundToLong - -/** - * Get failure model - * - * @param failureInterval The interval of failures occurring in s - * @return - */ -public fun getFailureModel(failureInterval: Double): FailureModel? { - return if (failureInterval > 0) { - Grid5000(Duration.ofSeconds(failureInterval.roundToLong())) - } else { - null - } -} +public data class CheckpointModel( + val checkpointWait: Long = 60 * 60 * 1000, + val checkpointTime: Long = 5 * 60 * 1000, +) diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFaultInjector.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFaultInjector.kt deleted file mode 100644 index 26084a1b..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/HostFaultInjector.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 org.opendc.compute.simulator.failure - -import org.apache.commons.math3.distribution.RealDistribution -import org.opendc.compute.simulator.SimHost -import org.opendc.compute.simulator.internal.HostFaultInjectorImpl -import java.time.Clock -import java.time.InstantSource -import kotlin.coroutines.CoroutineContext - -/** - * An interface for stochastically injecting faults into a set of hosts. - */ -public interface HostFaultInjector : AutoCloseable { - /** - * Start fault injection. - */ - public fun start() - - /** - * Stop fault injection into the system. - */ - public override fun close() - - public companion object { - /** - * Construct a new [HostFaultInjector]. - * - * @param context The scope to run the fault injector in. - * @param clock The [Clock] to keep track of simulation time. - * @param hosts The hosts to inject the faults into. - * @param iat The inter-arrival time distribution of the failures (in hours). - * @param selector The [VictimSelector] to select the host victims. - * @param fault The type of [HostFault] to inject. - */ - public operator fun invoke( - context: CoroutineContext, - clock: InstantSource, - hosts: Set<SimHost>, - iat: RealDistribution, - selector: VictimSelector, - fault: HostFault, - ): HostFaultInjector = HostFaultInjectorImpl(context, clock, hosts, iat, selector, fault) - } -} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/models/Grid5000.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/models/Grid5000.kt deleted file mode 100644 index 8aacc49d..00000000 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/failure/models/Grid5000.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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. - */ - -@file:JvmName("FailureModels") - -package org.opendc.compute.simulator.failure.models - -import org.apache.commons.math3.distribution.LogNormalDistribution -import org.apache.commons.math3.random.Well19937c -import org.opendc.compute.service.ComputeService -import org.opendc.compute.simulator.SimHost -import org.opendc.compute.simulator.failure.FailureModel -import org.opendc.compute.simulator.failure.HostFaultInjector -import org.opendc.compute.simulator.failure.StartStopHostFault -import org.opendc.compute.simulator.failure.StochasticVictimSelector -import java.time.Duration -import java.time.InstantSource -import java.util.random.RandomGenerator -import kotlin.coroutines.CoroutineContext -import kotlin.math.ln - -/** - * A [FailureModel] based on the GRID'5000 failure trace. - * - * This fault injector uses parameters from the GRID'5000 failure trace as described in - * "A Framework for the Study of Grid Inter-Operation Mechanisms", A. Iosup, 2009. - */ -public class Grid5000(private val failureInterval: Duration) : FailureModel { - override fun createInjector( - context: CoroutineContext, - clock: InstantSource, - service: ComputeService, - random: RandomGenerator, - ): HostFaultInjector { - val rng = Well19937c(random.nextLong()) - val hosts = service.hosts.map { it as SimHost }.toSet() - - // Parameters from A. Iosup, A Framework for the Study of Grid Inter-Operation Mechanisms, 2009 - // GRID'5000 - return HostFaultInjector( - context, - clock, - hosts, - iat = LogNormalDistribution(rng, ln(failureInterval.toHours().toDouble()), 1.03), - selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25), random), - fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)), - ) - } - - override fun toString(): String = "Grid5000FailureModel" -} diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/DefaultWorkloadMapper.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/DefaultWorkloadMapper.kt index c5293a8d..7d4b7302 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/DefaultWorkloadMapper.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/DefaultWorkloadMapper.kt @@ -38,7 +38,8 @@ internal object DefaultWorkloadMapper : SimWorkloadMapper { override fun createWorkload(server: Server): SimWorkload { val workload = delegate.createWorkload(server) - val bootWorkload = SimWorkloads.runtime(Duration.ofMillis(1), 0.8) + // FIXME: look at connecting this to frontend. Probably not needed since the duration is so small + val bootWorkload = SimWorkloads.runtime(Duration.ofMillis(1), 0.8, 0L, 0L) return SimWorkloads.chain(bootWorkload, workload) } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt index e268c506..cbdda0cb 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt @@ -186,7 +186,11 @@ internal class Guest( private fun doStop(target: ServerState) { assert(ctx != null) { "Invalid job state" } val ctx = ctx ?: return - ctx.shutdown() + if (target == ServerState.ERROR) { + ctx.shutdown(Exception("Stopped because of ERROR")) + } else { + ctx.shutdown() + } state = target } diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt deleted file mode 100644 index 690bf472..00000000 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/failure/HostFaultInjectorTest.kt +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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.compute.simulator.failure - -import io.mockk.coVerify -import io.mockk.mockk -import kotlinx.coroutines.delay -import org.apache.commons.math3.distribution.LogNormalDistribution -import org.apache.commons.math3.random.Well19937c -import org.junit.jupiter.api.Test -import org.opendc.compute.simulator.SimHost -import org.opendc.simulator.kotlin.runSimulation -import java.time.Duration -import java.time.InstantSource -import kotlin.coroutines.CoroutineContext -import kotlin.math.ln - -/** - * Test suite for [HostFaultInjector] class. - */ -class HostFaultInjectorTest { - /** - * Simple test case to test that nothing happens when the injector is not started. - */ - @Test - fun testInjectorNotStarted() = - runSimulation { - val host = mockk<SimHost>(relaxUnitFun = true) - - val injector = createSimpleInjector(coroutineContext, timeSource, setOf(host)) - - coVerify(exactly = 0) { host.fail() } - coVerify(exactly = 0) { host.recover() } - - injector.close() - } - - /** - * Simple test case to test a start stop fault where the machine is stopped and started after some time. - */ - @Test - fun testInjectorStopsMachine() = - runSimulation { - val host = mockk<SimHost>(relaxUnitFun = true) - - val injector = createSimpleInjector(coroutineContext, timeSource, setOf(host)) - - injector.start() - - delay(Duration.ofDays(55).toMillis()) - - injector.close() - - coVerify(exactly = 1) { host.fail() } - coVerify(exactly = 1) { host.recover() } - } - - /** - * Simple test case to test a start stop fault where multiple machines are stopped. - */ - @Test - fun testInjectorStopsMultipleMachines() = - runSimulation { - val hosts = - listOf<SimHost>( - mockk(relaxUnitFun = true), - mockk(relaxUnitFun = true), - ) - - val injector = createSimpleInjector(coroutineContext, timeSource, hosts.toSet()) - - injector.start() - - delay(Duration.ofDays(55).toMillis()) - - injector.close() - - coVerify(exactly = 1) { hosts[0].fail() } - coVerify(exactly = 1) { hosts[1].fail() } - coVerify(exactly = 1) { hosts[0].recover() } - coVerify(exactly = 1) { hosts[1].recover() } - } - - /** - * Create a simple start stop fault injector. - */ - private fun createSimpleInjector( - context: CoroutineContext, - clock: InstantSource, - hosts: Set<SimHost>, - ): HostFaultInjector { - val rng = Well19937c(0) - val iat = LogNormalDistribution(rng, ln(24 * 7.0), 1.03) - val selector = StochasticVictimSelector(LogNormalDistribution(rng, 1.88, 1.25)) - val fault = StartStopHostFault(LogNormalDistribution(rng, 8.89, 2.71)) - - return HostFaultInjector(context, clock, hosts, iat, selector, fault) - } -} diff --git a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyReader.kt b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyReader.kt index 63719c0a..f374b71f 100644 --- a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyReader.kt +++ b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyReader.kt @@ -28,17 +28,19 @@ import kotlinx.serialization.json.decodeFromStream import org.opendc.compute.topology.specs.TopologySpec import java.io.File import java.io.InputStream +import java.nio.file.Path +import kotlin.io.path.inputStream /** * A helper class for reading a topology specification file. */ public class TopologyReader { - @OptIn(ExperimentalSerializationApi::class) - public fun read(file: File): TopologySpec { - val input = file.inputStream() - val obj = Json.decodeFromStream<TopologySpec>(input) + public fun read(path: Path): TopologySpec { + return read(path.inputStream()) + } - return obj + public fun read(file: File): TopologySpec { + return read(file.inputStream()) } /** diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt index deb50f5c..7bea920e 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt @@ -51,4 +51,6 @@ public data class VirtualMachine( val stopTime: Instant, val trace: SimTrace, val interferenceProfile: VmInterferenceProfile?, -) +) { + val duration: Long = stopTime.toEpochMilli() - startTime.toEpochMilli() +} |
