From 028960fbf584c903156c713447194df56ec5059e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 18 Feb 2022 12:35:11 +0100 Subject: feat(utils): Add Pacer to pace scheduling cycles This change adds a new Pacer class that can pace the incoming scheduling requests into scheduling cycles by allowing the user to specify a scheduling quantum. --- .../compute/service/internal/ComputeServiceImpl.kt | 26 +++++++--------------- 1 file changed, 8 insertions(+), 18 deletions(-) (limited to 'opendc-compute') diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt index 27a6ecae..6df3c4f9 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt @@ -35,7 +35,7 @@ import org.opendc.compute.service.driver.Host import org.opendc.compute.service.driver.HostListener import org.opendc.compute.service.driver.HostState import org.opendc.compute.service.scheduler.ComputeScheduler -import org.opendc.utils.TimerScheduler +import org.opendc.utils.Pacer import java.time.Clock import java.time.Duration import java.util.* @@ -56,7 +56,7 @@ internal class ComputeServiceImpl( private val clock: Clock, meterProvider: MeterProvider, private val scheduler: ComputeScheduler, - private val schedulingQuantum: Duration + schedulingQuantum: Duration ) : ComputeService, HostListener { /** * The [CoroutineScope] of the service bounded by the lifecycle of the service. @@ -147,9 +147,9 @@ internal class ComputeServiceImpl( private val _serversActiveAttr = Attributes.of(AttributeKey.stringKey("state"), "active") /** - * The [TimerScheduler] to use for scheduling the scheduler cycles. + * The [Pacer] to use for scheduling the scheduler cycles. */ - private var timerScheduler: TimerScheduler = TimerScheduler(scope.coroutineContext, clock) + private val pacer = Pacer(scope.coroutineContext, clock, schedulingQuantum.toMillis(), ::doSchedule) override val hosts: Set get() = hostToView.keys @@ -354,28 +354,18 @@ internal class ComputeServiceImpl( * Indicate that a new scheduling cycle is needed due to a change to the service's state. */ private fun requestSchedulingCycle() { - // Bail out in case we have already requested a new cycle or the queue is empty. - if (timerScheduler.isTimerActive(Unit) || queue.isEmpty()) { + // Bail out in case the queue is empty. + if (queue.isEmpty()) { return } - val quantum = schedulingQuantum.toMillis() - - // We assume that the provisioner runs at a fixed slot every time quantum (e.g t=0, t=60, t=120). - // This is important because the slices of the VMs need to be aligned. - // We calculate here the delay until the next scheduling slot. - val delay = quantum - (clock.millis() % quantum) - - timerScheduler.startSingleTimer(Unit, delay) { - doSchedule() - } + pacer.enqueue() } /** * Run a single scheduling iteration. */ - private fun doSchedule() { - val now = clock.millis() + private fun doSchedule(now: Long) { while (queue.isNotEmpty()) { val request = queue.peek() -- cgit v1.2.3 From 52d35cd82905612f0ef9f7b7d88611300fb48ebe Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 18 Feb 2022 14:08:18 +0100 Subject: refactor(utils): Rename utils module to common module This change adds a new module, opendc-common, that contains functionality that is shared across OpenDC's modules. We move the existing utils module into this new module. --- opendc-compute/opendc-compute-service/build.gradle.kts | 2 +- .../kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt | 2 +- opendc-compute/opendc-compute-simulator/build.gradle.kts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'opendc-compute') diff --git a/opendc-compute/opendc-compute-service/build.gradle.kts b/opendc-compute/opendc-compute-service/build.gradle.kts index 33cafc45..b609b147 100644 --- a/opendc-compute/opendc-compute-service/build.gradle.kts +++ b/opendc-compute/opendc-compute-service/build.gradle.kts @@ -33,7 +33,7 @@ dependencies { api(platform(projects.opendcPlatform)) api(projects.opendcCompute.opendcComputeApi) api(projects.opendcTelemetry.opendcTelemetryApi) - implementation(projects.opendcUtils) + implementation(projects.opendcCommon) implementation(libs.kotlin.logging) implementation(libs.opentelemetry.semconv) diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt index 6df3c4f9..144b6573 100644 --- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt +++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt @@ -29,13 +29,13 @@ import io.opentelemetry.api.metrics.MeterProvider import io.opentelemetry.api.metrics.ObservableLongMeasurement import kotlinx.coroutines.* import mu.KotlinLogging +import org.opendc.common.util.Pacer import org.opendc.compute.api.* import org.opendc.compute.service.ComputeService import org.opendc.compute.service.driver.Host import org.opendc.compute.service.driver.HostListener import org.opendc.compute.service.driver.HostState import org.opendc.compute.service.scheduler.ComputeScheduler -import org.opendc.utils.Pacer import java.time.Clock import java.time.Duration import java.util.* diff --git a/opendc-compute/opendc-compute-simulator/build.gradle.kts b/opendc-compute/opendc-compute-simulator/build.gradle.kts index aaf69f78..686d9ca1 100644 --- a/opendc-compute/opendc-compute-simulator/build.gradle.kts +++ b/opendc-compute/opendc-compute-simulator/build.gradle.kts @@ -34,7 +34,7 @@ dependencies { api(projects.opendcCompute.opendcComputeService) api(projects.opendcSimulator.opendcSimulatorCompute) api(libs.commons.math3) - implementation(projects.opendcUtils) + implementation(projects.opendcCommon) implementation(libs.opentelemetry.semconv) implementation(libs.kotlin.logging) -- cgit v1.2.3 From 77aaf078650c054ccbaf5f46a71ab218390a571e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 18 Feb 2022 14:53:12 +0100 Subject: build: Remove opendc-platform module This change removes the opendc-platform module from the project. This module represented a Java platform which was previously used for sharing a set of dependency versions between subprojects. However, with the version catalogue that was added by Gradle, we currently do not use the platform anymore. --- opendc-compute/opendc-compute-api/build.gradle.kts | 4 ---- opendc-compute/opendc-compute-service/build.gradle.kts | 1 - opendc-compute/opendc-compute-simulator/build.gradle.kts | 1 - opendc-compute/opendc-compute-workload/build.gradle.kts | 1 - 4 files changed, 7 deletions(-) (limited to 'opendc-compute') diff --git a/opendc-compute/opendc-compute-api/build.gradle.kts b/opendc-compute/opendc-compute-api/build.gradle.kts index 880ee03d..2ac7e64c 100644 --- a/opendc-compute/opendc-compute-api/build.gradle.kts +++ b/opendc-compute/opendc-compute-api/build.gradle.kts @@ -26,7 +26,3 @@ description = "API interface for the OpenDC Compute service" plugins { `kotlin-library-conventions` } - -dependencies { - api(platform(projects.opendcPlatform)) -} diff --git a/opendc-compute/opendc-compute-service/build.gradle.kts b/opendc-compute/opendc-compute-service/build.gradle.kts index b609b147..b9437a73 100644 --- a/opendc-compute/opendc-compute-service/build.gradle.kts +++ b/opendc-compute/opendc-compute-service/build.gradle.kts @@ -30,7 +30,6 @@ plugins { } dependencies { - api(platform(projects.opendcPlatform)) api(projects.opendcCompute.opendcComputeApi) api(projects.opendcTelemetry.opendcTelemetryApi) implementation(projects.opendcCommon) diff --git a/opendc-compute/opendc-compute-simulator/build.gradle.kts b/opendc-compute/opendc-compute-simulator/build.gradle.kts index 686d9ca1..9a8cbfcc 100644 --- a/opendc-compute/opendc-compute-simulator/build.gradle.kts +++ b/opendc-compute/opendc-compute-simulator/build.gradle.kts @@ -30,7 +30,6 @@ plugins { } dependencies { - api(platform(projects.opendcPlatform)) api(projects.opendcCompute.opendcComputeService) api(projects.opendcSimulator.opendcSimulatorCompute) api(libs.commons.math3) diff --git a/opendc-compute/opendc-compute-workload/build.gradle.kts b/opendc-compute/opendc-compute-workload/build.gradle.kts index 28a5e1da..93e09b99 100644 --- a/opendc-compute/opendc-compute-workload/build.gradle.kts +++ b/opendc-compute/opendc-compute-workload/build.gradle.kts @@ -29,7 +29,6 @@ plugins { } dependencies { - api(platform(projects.opendcPlatform)) api(projects.opendcCompute.opendcComputeSimulator) implementation(projects.opendcTrace.opendcTraceApi) -- cgit v1.2.3 From c82b1725cc606769084155d6c4fba982cd320c41 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 18 Feb 2022 14:59:54 +0100 Subject: fix(compute): Disallow duplicate UIDs for SimHost This change fixes an issue with the ComputeServiceHelper where it allowed users to register multiple SimHost objects with the same UID. See this issue for more information: https://github.com/atlarge-research/opendc/issues/51 --- .../src/main/kotlin/org/opendc/compute/simulator/SimHost.kt | 6 ++++++ .../main/kotlin/org/opendc/compute/workload/ComputeServiceHelper.kt | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'opendc-compute') 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 95921e8b..43f33f27 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 @@ -249,6 +249,12 @@ public class SimHost( machine.cancel() } + override fun hashCode(): Int = uid.hashCode() + + override fun equals(other: Any?): Boolean { + return other is SimHost && uid == other.uid + } + override fun toString(): String = "SimHost[uid=$uid,name=$name,model=$model]" public suspend fun fail() { diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeServiceHelper.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeServiceHelper.kt index a1a65da3..4b0b343f 100644 --- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeServiceHelper.kt +++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeServiceHelper.kt @@ -169,7 +169,7 @@ public class ComputeServiceHelper( optimize = optimize ) - _hosts.add(host) + require(_hosts.add(host)) { "Host with uid ${spec.uid} already exists" } service.addHost(host) return host -- cgit v1.2.3