From c2250720d694c6e7e19b3c0ba2fc27a124d3cadb Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 31 Mar 2021 14:21:19 +0200 Subject: exp: Add trace reader for Serverless experiments This change adds the trace reader for the serverless experiments as described in #48. --- .../experiments/serverless/trace/FunctionSample.kt | 44 ++++++++++ .../experiments/serverless/trace/FunctionTrace.kt | 28 +++++++ .../serverless/trace/ServerlessTraceReader.kt | 94 ++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionSample.kt create mode 100644 simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTrace.kt create mode 100644 simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/ServerlessTraceReader.kt (limited to 'simulator/opendc-experiments/opendc-experiments-serverless20/src') diff --git a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionSample.kt b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionSample.kt new file mode 100644 index 00000000..492f44b9 --- /dev/null +++ b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionSample.kt @@ -0,0 +1,44 @@ +/* + * 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.experiments.serverless.trace + +/** + * A sample of a single function. + * + * @param timestamp The timestamp of the function. + * @param duration The average execution time of the function. + * @param invocations The number of invocations. + * @param provisionedCpu The provisioned CPU for this function in MHz. + * @param provisionedMem The amount of memory provisioned for this function in MB. + * @param cpuUsage The actual CPU usage in MHz. + * @param memUsage The actual memory usage in MB. + */ +public data class FunctionSample( + val timestamp: Long, + val duration: Long, + val invocations: Int, + val provisionedCpu: Int, + val provisionedMem: Int, + val cpuUsage: Double, + val memUsage: Double +) diff --git a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTrace.kt b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTrace.kt new file mode 100644 index 00000000..97c98e2a --- /dev/null +++ b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTrace.kt @@ -0,0 +1,28 @@ +/* + * 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.experiments.serverless.trace + +/** + * A trace for a single function + */ +public data class FunctionTrace(val id: String, val samples: List) diff --git a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/ServerlessTraceReader.kt b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/ServerlessTraceReader.kt new file mode 100644 index 00000000..87dd33fa --- /dev/null +++ b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/ServerlessTraceReader.kt @@ -0,0 +1,94 @@ +/* + * 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.experiments.serverless.trace + +import java.io.File + +/** + * A trace reader for the serverless workload trace used in the OpenDC Serverless thesis. + */ +public class ServerlessTraceReader { + /** + * Parse the traces at the specified [path]. + */ + public fun parse(path: File): List { + return if (path.isFile) { + listOf(parseSingle(path)) + } else { + path.walk() + .filterNot { it.isDirectory } + .map { parseSingle(it) } + .toList() + } + } + + /** + * Parse a single trace. + */ + private fun parseSingle(path: File): FunctionTrace { + val samples = mutableListOf() + val id = path.nameWithoutExtension + var idx = 0 + + var timestampCol = 0 + var invocationsCol = 0 + var execTimeCol = 0 + var provCpuCol = 0 + var provMemCol = 0 + var cpuUsageCol = 0 + var memoryUsageCol = 0 + + path.forEachLine { line -> + if (line.startsWith("#") && line.isNotBlank()) { + return@forEachLine + } + + val values = line.split(",") + + /* Header parsing */ + if (++idx == 0){ + val header = values.mapIndexed { col, name -> Pair(name.trim(), col) }.toMap() + timestampCol = header["Timestamp [ms]"]!! + invocationsCol = header["Invocations"]!! + execTimeCol = header["Avg Exec time per Invocation"]!! + provCpuCol = header["Provisioned CPU [Mhz]"]!! + provMemCol = header["Provisioned Memory [mb]"]!! + cpuUsageCol = header["Avg cpu usage per Invocation [Mhz]"]!! + memoryUsageCol = header["Avg mem usage per Invocation [mb]"]!! + return@forEachLine + } + + val timestamp = values[timestampCol].trim().toLong() + val invocations = values[invocationsCol].trim().toInt() + val execTime = values[execTimeCol].trim().toLong() + val provisionedCpu = values[provCpuCol].trim().toInt() + val provisionedMemory = values[provMemCol].trim().toInt() + val cpuUsage = values[cpuUsageCol].trim().toDouble() + val memoryUsage = values[memoryUsageCol].trim().toDouble() + + samples.add(FunctionSample(timestamp, execTime, invocations, provisionedCpu, provisionedMemory, cpuUsage, memoryUsage)) + } + + return FunctionTrace(id, samples) + } +} -- cgit v1.2.3 From 8df422ca5164bd712caf594951669ebeb656f5fb Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 31 Mar 2021 15:26:45 +0200 Subject: exp: Add experiment testing the serverless module This change adds an experiments testing the OpenDC Serverless module. --- .../experiments/serverless/ServerlessExperiment.kt | 130 +++++++++++++++++++++ .../experiments/serverless/trace/FunctionTrace.kt | 2 +- .../serverless/trace/FunctionTraceWorkload.kt | 34 ++++++ .../serverless/trace/ServerlessTraceReader.kt | 27 +++-- 4 files changed, 185 insertions(+), 8 deletions(-) create mode 100644 simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt create mode 100644 simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt (limited to 'simulator/opendc-experiments/opendc-experiments-serverless20/src') diff --git a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt new file mode 100644 index 00000000..e4dc6753 --- /dev/null +++ b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt @@ -0,0 +1,130 @@ +/* + * 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.experiments.serverless + +import io.opentelemetry.api.metrics.MeterProvider +import io.opentelemetry.sdk.metrics.SdkMeterProvider +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runBlockingTest +import mu.KotlinLogging +import org.opendc.experiments.serverless.trace.FunctionTraceWorkload +import org.opendc.experiments.serverless.trace.ServerlessTraceReader +import org.opendc.harness.dsl.Experiment +import org.opendc.harness.dsl.anyOf +import org.opendc.serverless.service.ServerlessService +import org.opendc.serverless.service.router.RandomRoutingPolicy +import org.opendc.serverless.simulator.SimFunctionDeployer +import org.opendc.simulator.compute.SimMachineModel +import org.opendc.simulator.compute.model.MemoryUnit +import org.opendc.simulator.compute.model.ProcessingNode +import org.opendc.simulator.compute.model.ProcessingUnit +import org.opendc.simulator.utils.DelayControllerClockAdapter +import org.opendc.telemetry.sdk.toOtelClock +import java.io.File +import kotlin.math.max + +/** + * A reproduction of the experiments of Soufiane Jounaid's BSc Computer Science thesis: + * OpenDC Serverless: Design, Implementation and Evaluation of a FaaS Platform Simulator. + */ +public class ServerlessExperiment : Experiment("Serverless") { + /** + * The logger for this portfolio instance. + */ + private val logger = KotlinLogging.logger {} + + /** + * The path to where the traces are located. + */ + private val tracePath by anyOf(File("../../input/traces/serverless")) + + /** + * The path to where the output results should be written. + */ + private val outputPath by anyOf(File("output/")) + + /** + * The routing policy to test. + */ + private val routingPolicy by anyOf(RandomRoutingPolicy()) + + @OptIn(ExperimentalCoroutinesApi::class) + override fun doRun(repeat: Int): Unit = runBlockingTest { + val clock = DelayControllerClockAdapter(this) + val meterProvider: MeterProvider = SdkMeterProvider + .builder() + .setClock(clock.toOtelClock()) + .build() + + val trace = ServerlessTraceReader().parse(tracePath) + val traceById = trace.associateBy { it.id } + val deployer = SimFunctionDeployer(clock, this, createMachineModel()) { FunctionTraceWorkload(traceById.getValue(it.name)) } + val service = ServerlessService(coroutineContext, clock, meterProvider.get("opendc-serverless"), deployer, routingPolicy) + val client = service.newClient() + + coroutineScope { + for (entry in trace) { + launch { + val function = client.newFunction(entry.id, entry.maxMemory.toLong()) + var offset = Long.MIN_VALUE + + for (sample in entry.samples) { + if (sample.invocations == 0) { + continue + } + + if (offset < 0) { + offset = sample.timestamp - clock.millis() + } + + delay(max(0, (sample.timestamp - offset) - clock.millis())) + + logger.info { "Invoking function ${entry.id} ${sample.invocations} times [${sample.timestamp}]" } + + repeat(sample.invocations) { + function.invoke() + } + } + } + } + } + + client.close() + service.close() + } + + /** + * Construct the machine model to test with. + */ + private fun createMachineModel(): SimMachineModel { + val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) + + return SimMachineModel( + cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 1000.0) }, + memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) } + ) + } +} diff --git a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTrace.kt b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTrace.kt index 97c98e2a..4fea6b96 100644 --- a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTrace.kt +++ b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTrace.kt @@ -25,4 +25,4 @@ package org.opendc.experiments.serverless.trace /** * A trace for a single function */ -public data class FunctionTrace(val id: String, val samples: List) +public data class FunctionTrace(val id: String, val maxMemory: Int, val samples: List) diff --git a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt new file mode 100644 index 00000000..7d824857 --- /dev/null +++ b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/FunctionTraceWorkload.kt @@ -0,0 +1,34 @@ +/* + * 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.experiments.serverless.trace + +import org.opendc.serverless.simulator.workload.SimServerlessWorkload +import org.opendc.simulator.compute.workload.SimTraceWorkload +import org.opendc.simulator.compute.workload.SimWorkload + +/** + * A [SimServerlessWorkload] for a [FunctionTrace]. + */ +public class FunctionTraceWorkload(trace: FunctionTrace) : SimServerlessWorkload, SimWorkload by SimTraceWorkload(trace.samples.asSequence().map { SimTraceWorkload.Fragment(it.duration, it.cpuUsage, 1) }) { + override suspend fun invoke() {} +} diff --git a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/ServerlessTraceReader.kt b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/ServerlessTraceReader.kt index 87dd33fa..6dc35c59 100644 --- a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/ServerlessTraceReader.kt +++ b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/trace/ServerlessTraceReader.kt @@ -22,12 +22,19 @@ package org.opendc.experiments.serverless.trace +import mu.KotlinLogging import java.io.File +import kotlin.math.max /** * A trace reader for the serverless workload trace used in the OpenDC Serverless thesis. */ public class ServerlessTraceReader { + /** + * The logger for this portfolio instance. + */ + private val logger = KotlinLogging.logger {} + /** * Parse the traces at the specified [path]. */ @@ -37,7 +44,10 @@ public class ServerlessTraceReader { } else { path.walk() .filterNot { it.isDirectory } - .map { parseSingle(it) } + .map { file -> + logger.info { "Parsing $file" } + parseSingle(file) + } .toList() } } @@ -57,16 +67,17 @@ public class ServerlessTraceReader { var provMemCol = 0 var cpuUsageCol = 0 var memoryUsageCol = 0 + var maxMemory = 0 path.forEachLine { line -> - if (line.startsWith("#") && line.isNotBlank()) { - return@forEachLine - } + if (line.startsWith("#") && line.isNotBlank()) { + return@forEachLine + } val values = line.split(",") /* Header parsing */ - if (++idx == 0){ + if (idx++ == 0) { val header = values.mapIndexed { col, name -> Pair(name.trim(), col) }.toMap() timestampCol = header["Timestamp [ms]"]!! invocationsCol = header["Invocations"]!! @@ -78,7 +89,7 @@ public class ServerlessTraceReader { return@forEachLine } - val timestamp = values[timestampCol].trim().toLong() + val timestamp = values[timestampCol].trim().toLong() val invocations = values[invocationsCol].trim().toInt() val execTime = values[execTimeCol].trim().toLong() val provisionedCpu = values[provCpuCol].trim().toInt() @@ -86,9 +97,11 @@ public class ServerlessTraceReader { val cpuUsage = values[cpuUsageCol].trim().toDouble() val memoryUsage = values[memoryUsageCol].trim().toDouble() + maxMemory = max(maxMemory, provisionedMemory) + samples.add(FunctionSample(timestamp, execTime, invocations, provisionedCpu, provisionedMemory, cpuUsage, memoryUsage)) } - return FunctionTrace(id, samples) + return FunctionTrace(id, maxMemory, samples) } } -- cgit v1.2.3 From 831ba3d882a46dad2abe6ac281b736b729dc7080 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 1 Apr 2021 21:14:34 +0200 Subject: serverless: Model cold start delays --- .../org/opendc/experiments/serverless/ServerlessExperiment.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'simulator/opendc-experiments/opendc-experiments-serverless20/src') diff --git a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt index e4dc6753..757617f8 100644 --- a/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt +++ b/simulator/opendc-experiments/opendc-experiments-serverless20/src/main/kotlin/org/opendc/experiments/serverless/ServerlessExperiment.kt @@ -37,6 +37,8 @@ import org.opendc.harness.dsl.anyOf import org.opendc.serverless.service.ServerlessService import org.opendc.serverless.service.router.RandomRoutingPolicy import org.opendc.serverless.simulator.SimFunctionDeployer +import org.opendc.serverless.simulator.delay.ColdStartModel +import org.opendc.serverless.simulator.delay.StochasticDelayInjector import org.opendc.simulator.compute.SimMachineModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.model.ProcessingNode @@ -44,6 +46,7 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.utils.DelayControllerClockAdapter import org.opendc.telemetry.sdk.toOtelClock import java.io.File +import java.util.* import kotlin.math.max /** @@ -71,6 +74,11 @@ public class ServerlessExperiment : Experiment("Serverless") { */ private val routingPolicy by anyOf(RandomRoutingPolicy()) + /** + * The cold start models to test. + */ + private val coldStartModel by anyOf(ColdStartModel.LAMBDA, ColdStartModel.AZURE, ColdStartModel.GOOGLE) + @OptIn(ExperimentalCoroutinesApi::class) override fun doRun(repeat: Int): Unit = runBlockingTest { val clock = DelayControllerClockAdapter(this) @@ -81,7 +89,8 @@ public class ServerlessExperiment : Experiment("Serverless") { val trace = ServerlessTraceReader().parse(tracePath) val traceById = trace.associateBy { it.id } - val deployer = SimFunctionDeployer(clock, this, createMachineModel()) { FunctionTraceWorkload(traceById.getValue(it.name)) } + val delayInjector = StochasticDelayInjector(coldStartModel, Random()) + val deployer = SimFunctionDeployer(clock, this, createMachineModel(), delayInjector) { FunctionTraceWorkload(traceById.getValue(it.name)) } val service = ServerlessService(coroutineContext, clock, meterProvider.get("opendc-serverless"), deployer, routingPolicy) val client = service.newClient() -- cgit v1.2.3