summaryrefslogtreecommitdiff
path: root/opendc-compute
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-compute')
-rw-r--r--opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt126
-rw-r--r--opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Flavor.kt2
-rw-r--r--opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Resource.kt5
-rw-r--r--opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Task.kt79
-rw-r--r--opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/TaskState.kt29
-rw-r--r--opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTrace.kt8
-rw-r--r--opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTraceLoader.kt4
-rw-r--r--opendc-compute/opendc-compute-failure/build.gradle.kts1
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt4
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt18
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt4
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/SampleBasedFailureModel.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/TraceBasedFailureModel.kt4
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/G5k06.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Lanl05.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Ldns04.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Microsoft99.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Nd07cpu.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Overnet03.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Pl05.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/PrefabFailureModelFactory.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Skype06.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/prefab/Websites02.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt2
-rw-r--r--opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt2
-rw-r--r--opendc-compute/opendc-compute-service/build.gradle.kts40
-rw-r--r--opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/Host.java137
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt386
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceFlavorTest.kt67
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceImageTest.kt67
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceTaskTest.kt442
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt536
-rw-r--r--opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml38
-rw-r--r--opendc-compute/opendc-compute-simulator/build.gradle.kts7
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/host/HostListener.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostListener.java)14
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/host/HostModel.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostModel.java)4
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/host/HostState.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostState.java)2
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java)193
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/HostView.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/HostView.java)14
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceFlavor.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceFlavor.java)19
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceImage.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceImage.java)8
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceTask.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceTask.java)153
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/GuestCpuStats.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestCpuStats.java)8
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/GuestSystemStats.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestSystemStats.java)2
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/HostCpuStats.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostCpuStats.java)10
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/HostSystemStats.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostSystemStats.java)6
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/SchedulerStats.java (renamed from opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/telemetry/SchedulerStats.java)10
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/MutableServiceRegistry.kt65
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistry.kt61
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistryImpl.kt76
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt378
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimMetaWorkloadMapper.kt35
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimWorkloadMapper.kt37
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/TaskWatcher.kt (renamed from opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/TaskWatcher.kt)11
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt369
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/DefaultWorkloadMapper.kt46
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt247
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/GuestListener.kt6
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeMonitorProvisioningStep.kt16
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeServiceProvisioningStep.kt4
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeSteps.kt10
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt24
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/Provisioner.kt4
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ProvisioningContext.kt6
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeScheduler.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt)11
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt)16
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/FilterScheduler.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt)14
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ReplayScheduler.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt)10
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/ComputeFilter.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt)12
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/DifferentHostFilter.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt)10
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/HostFilter.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt)9
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/InstanceCountFilter.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt)8
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/RamFilter.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt)12
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/SameHostFilter.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt)10
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuCapacityFilter.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt)13
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuFilter.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt)12
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/CoreRamWeigher.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt)8
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/HostWeigher.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt)13
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/InstanceCountWeigher.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt)8
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/RamWeigher.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt)8
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VCpuCapacityWeigher.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt)10
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VCpuWeigher.kt (renamed from opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt)8
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/ComputeMetricReader.kt)204
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMonitor.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/ComputeMonitor.kt)8
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ComputeExportConfig.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/ComputeExportConfig.kt)22
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/DfltHostExportColumns.kt)22
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltServiceExportColumns.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/DfltServiceExportColumns.kt)26
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/DfltTaskExportColumns.kt)18
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ParquetComputeMonitor.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/ParquetComputeMonitor.kt)10
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/README.md (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/README.md)6
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostInfo.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/HostInfo.kt)4
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/HostTableReader.kt)18
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceData.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/ServiceData.kt)6
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReader.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/ServiceTableReader.kt)17
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskInfo.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/TaskInfo.kt)4
-rw-r--r--opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReader.kt (renamed from opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/TaskTableReader.kt)16
-rw-r--r--opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt393
-rw-r--r--opendc-compute/opendc-compute-telemetry/build.gradle.kts44
-rw-r--r--opendc-compute/opendc-compute-telemetry/src/test/resources/log4j2.xml38
-rw-r--r--opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt15
-rw-r--r--opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/HostSpec.kt11
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt4
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt70
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/Task.kt (renamed from opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/VirtualMachine.kt)13
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt6
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt14
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt6
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt4
108 files changed, 1232 insertions, 3827 deletions
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
deleted file mode 100644
index 9e24a3fd..00000000
--- a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/ComputeClient.kt
+++ /dev/null
@@ -1,126 +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.api
-
-import org.opendc.simulator.compute.workload.SimWorkload
-import java.util.UUID
-
-/**
- * A client interface for the OpenDC Compute service.
- */
-public interface ComputeClient : AutoCloseable {
- /**
- * Obtain the list of [Flavor]s accessible by the requesting user.
- */
- public fun queryFlavors(): List<Flavor>
-
- /**
- * Obtain a [Flavor] by its unique identifier.
- *
- * @param id The identifier of the flavor.
- */
- public fun findFlavor(id: UUID): Flavor?
-
- /**
- * Create a new [Flavor] instance at this compute service.
- *
- * @param name The name of the flavor.
- * @param cpuCount The amount of CPU cores for this flavor.
- * @param memorySize The size of the memory in MB.
- * @param labels The identifying labels of the image.
- * @param meta The non-identifying meta-data of the image.
- */
- public fun newFlavor(
- name: String,
- cpuCount: Int,
- memorySize: Long,
- labels: Map<String, String> = emptyMap(),
- meta: Map<String, Any> = emptyMap(),
- ): Flavor
-
- /**
- * Obtain the list of [Image]s accessible by the requesting user.
- */
- public fun queryImages(): List<Image>
-
- /**
- * Obtain a [Image] by its unique identifier.
- *
- * @param id The identifier of the image.
- */
- public fun findImage(id: UUID): Image?
-
- /**
- * Create a new [Image] instance at this compute service.
- *
- * @param name The name of the image.
- * @param labels The identifying labels of the image.
- * @param meta The non-identifying meta-data of the image.
- */
- public fun newImage(
- name: String,
- labels: Map<String, String> = emptyMap(),
- meta: Map<String, Any> = emptyMap(),
- ): Image
-
- /**
- * Obtain the list of [Task]s accessible by the requesting user.
- */
- public fun queryTasks(): List<Task>
-
- /**
- * Obtain a [Task] by its unique identifier.
- *
- * @param id The identifier of the task.
- */
- public fun findTask(id: UUID): Task?
-
- /**
- * Create a new [Task] instance at this compute service.
- *
- * @param name The name of the task to deploy.
- * @param image The image to be deployed.
- * @param flavor The flavor of the machine instance to run this [image] on.
- * @param labels The identifying labels of the task.
- * @param meta The non-identifying meta-data of the task.
- * @param start A flag to indicate that the task should be started immediately.
- */
- public fun newTask(
- name: String,
- image: Image,
- flavor: Flavor,
- labels: Map<String, String> = emptyMap(),
- meta: Map<String, Any> = emptyMap(),
- start: Boolean = true,
- ): Task
-
- public fun rescheduleTask(
- task: Task,
- workload: SimWorkload,
- )
-
- /**
- * Release the resources associated with this client, preventing any further API calls.
- */
- public override fun close()
-}
diff --git a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Flavor.kt b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Flavor.kt
index 99042c24..e88379f6 100644
--- a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Flavor.kt
+++ b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Flavor.kt
@@ -23,7 +23,7 @@
package org.opendc.compute.api
/**
- * Flavors define the compute and memory capacity of [Task] instance. To put it simply, a flavor is an available
+ * Flavors define the compute and memory capacity of [ServiceTask] instance. To put it simply, a flavor is an available
* hardware configuration for a task. It defines the size of a virtual task that can be launched.
*/
public interface Flavor : Resource {
diff --git a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Resource.kt b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Resource.kt
index 58082130..2c3822a7 100644
--- a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Resource.kt
+++ b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Resource.kt
@@ -39,11 +39,6 @@ public interface Resource {
public val name: String
/**
- * The identifying labels attached to the resource.
- */
- public val labels: Map<String, String>
-
- /**
* The non-identifying metadata attached to the resource.
*/
public val meta: Map<String, Any>
diff --git a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Task.kt b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Task.kt
deleted file mode 100644
index 23f2cb91..00000000
--- a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/Task.kt
+++ /dev/null
@@ -1,79 +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.api
-
-import java.time.Instant
-
-/**
- * A stateful object representing a task instance that is running on some physical or virtual machine.
- */
-public interface Task : Resource {
- /**
- * The flavor of the task.
- */
- public val flavor: Flavor
-
- /**
- * The image of the task.
- */
- public val image: Image
-
- /**
- * The last known state of the task.
- */
- public val state: TaskState
-
- /**
- * The number of times a Task has been stopped due to failures
- */
- public val numFailures: Int
-
- /**
- * The most recent moment in time when the task was launched.
- */
- public val launchedAt: Instant?
-
- /**
- * Request the task to be started.
- */
- public fun start()
-
- /**
- * Request the task to be stopped.
- */
- public fun stop()
-
- /**
- * Register the specified [TaskWatcher] to watch the state of the task.
- *
- * @param watcher The watcher to register for the task.
- */
- public fun watch(watcher: TaskWatcher)
-
- /**
- * De-register the specified [TaskWatcher] from the task to stop it from receiving events.
- *
- * @param watcher The watcher to de-register from the task.
- */
- public fun unwatch(watcher: TaskWatcher)
-}
diff --git a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/TaskState.kt b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/TaskState.kt
index a093ff47..f3f2ca6f 100644
--- a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/TaskState.kt
+++ b/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/TaskState.kt
@@ -27,14 +27,15 @@ package org.opendc.compute.api
*/
public enum class TaskState {
/**
- * Resources are being allocated for the instance. The instance is not running yet.
+ * A static task is created
+ *
*/
- PROVISIONING,
+ CREATED,
/**
- * A user shut down the instance.
+ * Resources are being allocated for the instance. The instance is not running yet.
*/
- TERMINATED,
+ PROVISIONING,
/**
* The task instance is booting up or running.
@@ -42,12 +43,26 @@ public enum class TaskState {
RUNNING,
/**
- * The task is in an error state.
+ * The task is in a failed state.
+ */
+ FAILED,
+
+ /**
+ * The task has been terminated due to too many failures
+ *
+ */
+ TERMINATED,
+
+ /**
+ * The task has been completed successfully
+ *
*/
- ERROR,
+ COMPLETED,
/**
- * The task has been deleted and cannot be started later on.
+ * Task has been deleted
+ *
+ * @constructor Create empty Deleted
*/
DELETED,
}
diff --git a/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTrace.kt b/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTrace.kt
index 2ba3e4e3..6eb7a762 100644
--- a/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTrace.kt
+++ b/opendc-compute/opendc-compute-carbon/src/main/kotlin/org/opendc/compute/carbon/CarbonTrace.kt
@@ -40,7 +40,7 @@ import java.time.Instant
public data class CarbonFragment(
var startTime: Long,
var endTime: Long,
- var carbonIntensity: Double,
+ var carbonIntensity: Float,
) {
init {
require(endTime > startTime) {
@@ -67,7 +67,7 @@ public class CarbonTrace(reports: List<CarbonFragment>? = null) {
return index < numberOfReports
}
- public fun getCarbonIntensity(timestamp: Instant): Double {
+ public fun getCarbonIntensity(timestamp: Instant): Float {
return getCarbonIntensity(timestamp.toEpochMilli())
}
@@ -79,9 +79,9 @@ public class CarbonTrace(reports: List<CarbonFragment>? = null) {
* @param timestamp
* @return The carbon intensity at the given timestamp in gCO2/kWh
*/
- public fun getCarbonIntensity(timestamp: Long): Double {
+ public fun getCarbonIntensity(timestamp: Long): Float {
if (reports == null) {
- return 0.0
+ return 0.0f
}
var currentFragment: CarbonFragment
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 b66aedf9..12340adf 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
@@ -56,7 +56,7 @@ public class CarbonTraceLoader {
try {
while (reader.nextRow()) {
val startTime = reader.getInstant(startTimeCol)!!
- val carbonIntensity = reader.getDouble(carbonIntensityCol)
+ val carbonIntensity = reader.getFloat(carbonIntensityCol)
builder.add(startTime, carbonIntensity)
}
@@ -106,7 +106,7 @@ public class CarbonTraceLoader {
*/
fun add(
startTime: Instant,
- carbonIntensity: Double,
+ carbonIntensity: Float,
) {
fragments.add(
CarbonFragment(startTime.toEpochMilli(), Long.MAX_VALUE, carbonIntensity),
diff --git a/opendc-compute/opendc-compute-failure/build.gradle.kts b/opendc-compute/opendc-compute-failure/build.gradle.kts
index d6ec9116..3bd7af83 100644
--- a/opendc-compute/opendc-compute-failure/build.gradle.kts
+++ b/opendc-compute/opendc-compute-failure/build.gradle.kts
@@ -32,7 +32,6 @@ dependencies {
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)
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt
index 4134c58a..a1e4c489 100644
--- a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/HostFault.kt
@@ -22,8 +22,8 @@
package org.opendc.compute.failure.hostfault
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.simulator.SimHost
+import org.opendc.compute.simulator.host.SimHost
+import org.opendc.compute.simulator.service.ComputeService
/**
* Interface responsible for applying the fault to a host.
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt
index 0bebca66..c7ddc5b5 100644
--- a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/hostfault/StartStopHostFault.kt
@@ -23,10 +23,8 @@
package org.opendc.compute.failure.hostfault
import kotlinx.coroutines.delay
-import org.opendc.compute.api.ComputeClient
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.simulator.SimHost
-import org.opendc.simulator.compute.workload.SimWorkload
+import org.opendc.compute.simulator.host.SimHost
+import org.opendc.compute.simulator.service.ComputeService
/**
* A type of [HostFault] where the hosts are stopped and recover after a given amount of time.
@@ -38,18 +36,20 @@ public class StartStopHostFault(
victims: List<SimHost>,
faultDuration: Long,
) {
- val client: ComputeClient = service.newClient()
+ val client: ComputeService.ComputeClient = service.newClient()
for (host in victims) {
- val tasks = host.instances
+ val guests = host.getGuests()
- val sortedTasks = tasks.sortedBy { it.name }
- val snapshots = sortedTasks.map { (it.meta["workload"] as SimWorkload).getSnapshot() }
+ val snapshots = guests.map { it.virtualMachine!!.getActiveWorkload().getSnapshot() }
+ val tasks = guests.map { it.task }
host.fail()
- for ((task, snapshot) in sortedTasks.zip(snapshots)) {
+ for ((task, snapshot) in tasks.zip(snapshots)) {
client.rescheduleTask(task, snapshot)
}
+
+ print("test")
}
delay(faultDuration)
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt
index 5f05d96c..f0cee5f2 100644
--- a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/models/FailureModel.kt
@@ -29,8 +29,8 @@ import kotlinx.coroutines.launch
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.host.SimHost
+import org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index 3ae66f6f..ae4077e8 100644
--- 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
@@ -24,7 +24,7 @@ package org.opendc.compute.failure.models
import kotlinx.coroutines.delay
import org.apache.commons.math3.distribution.RealDistribution
-import org.opendc.compute.service.ComputeService
+import org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index f1ff09e9..cab96cd8 100644
--- 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
@@ -23,7 +23,7 @@
package org.opendc.compute.failure.models
import kotlinx.coroutines.delay
-import org.opendc.compute.service.ComputeService
+import org.opendc.compute.simulator.service.ComputeService
import org.opendc.trace.Trace
import org.opendc.trace.conv.FAILURE_DURATION
import org.opendc.trace.conv.FAILURE_INTENSITY
@@ -71,7 +71,7 @@ public class TraceBasedFailureModel(
service: ComputeService,
random: RandomGenerator,
pathToTrace: String,
- private val repeat: Boolean = true,
+ private val repeat: Boolean = false,
) : FailureModel(context, clock, service, random) {
private val failureList = loadTrace(pathToTrace)
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
index da58250d..1c1d65d2 100644
--- 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
@@ -29,7 +29,7 @@ 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 org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index 3e722630..d3d4d704 100644
--- 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
@@ -29,7 +29,7 @@ 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 org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index 4a8b3c0f..fd4bd351 100644
--- 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
@@ -29,7 +29,7 @@ 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 org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index 725f6622..db27efb8 100644
--- 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
@@ -29,7 +29,7 @@ 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 org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index 100a3a8d..eac2df0c 100644
--- 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
@@ -29,7 +29,7 @@ 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 org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index 4f5e3f84..965e861d 100644
--- 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
@@ -29,7 +29,7 @@ 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 org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index 3e1f1b58..5102bd6b 100644
--- 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
@@ -29,7 +29,7 @@ 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 org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index 477f3ac4..361620b0 100644
--- 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
@@ -25,7 +25,7 @@
package org.opendc.compute.failure.prefab
import org.opendc.compute.failure.models.SampleBasedFailureModel
-import org.opendc.compute.service.ComputeService
+import org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index 7495bf66..30f7ec1b 100644
--- 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
@@ -29,7 +29,7 @@ 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 org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
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
index 77bb0d64..df37c27b 100644
--- 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
@@ -29,7 +29,7 @@ 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 org.opendc.compute.simulator.service.ComputeService
import java.time.InstantSource
import java.util.random.RandomGenerator
import kotlin.coroutines.CoroutineContext
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt
index fef60eb3..9b92cf33 100644
--- a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/StochasticVictimSelector.kt
@@ -22,7 +22,7 @@
package org.opendc.compute.failure.victimselector
-import org.opendc.compute.simulator.SimHost
+import org.opendc.compute.simulator.host.SimHost
import java.util.SplittableRandom
import java.util.random.RandomGenerator
import kotlin.math.max
diff --git a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt
index 955cbced..b276b8b4 100644
--- a/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt
+++ b/opendc-compute/opendc-compute-failure/src/main/kotlin/org/opendc/compute/failure/victimselector/VictimSelector.kt
@@ -22,7 +22,7 @@
package org.opendc.compute.failure.victimselector
-import org.opendc.compute.simulator.SimHost
+import org.opendc.compute.simulator.host.SimHost
/**
* Interface responsible for selecting the victim(s) for fault injection.
diff --git a/opendc-compute/opendc-compute-service/build.gradle.kts b/opendc-compute/opendc-compute-service/build.gradle.kts
deleted file mode 100644
index cd25e05c..00000000
--- a/opendc-compute/opendc-compute-service/build.gradle.kts
+++ /dev/null
@@ -1,40 +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.
- */
-
-description = "OpenDC Compute Service implementation"
-
-// Build configuration
-plugins {
- `kotlin-library-conventions`
-}
-
-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)
- testRuntimeOnly(libs.log4j.core)
- testRuntimeOnly(libs.log4j.slf4j)
-}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/Host.java b/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/Host.java
deleted file mode 100644
index 546f774b..00000000
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/Host.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2022 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.service.driver;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import org.opendc.compute.api.Task;
-import org.opendc.compute.service.driver.telemetry.GuestCpuStats;
-import org.opendc.compute.service.driver.telemetry.GuestSystemStats;
-import org.opendc.compute.service.driver.telemetry.HostCpuStats;
-import org.opendc.compute.service.driver.telemetry.HostSystemStats;
-
-/**
- * Base interface for representing compute resources that host virtualized {@link Task} instances.
- */
-public interface Host {
- /**
- * Return a unique identifier representing the host.
- */
- UUID getUid();
-
- /**
- * Return the name of this host.
- */
- String getName();
-
- /**
- * Return the machine model of the host.
- */
- HostModel getModel();
-
- /**
- * Return the state of the host.
- */
- HostState getState();
-
- /**
- * Return the meta-data associated with the host.
- */
- Map<String, ?> getMeta();
-
- /**
- * Return the {@link Task} instances known to the host.
- */
- Set<Task> getInstances();
-
- /**
- * Determine whether the specified <code>task</code> can still fit on this host.
- */
- boolean canFit(Task task);
-
- /**
- * Register the specified <code>task</code> on the host.
- */
- void spawn(Task task);
-
- /**
- * Determine whether the specified <code>task</code> exists on the host.
- */
- boolean contains(Task task);
-
- /**
- * Start the task if it is currently not running on this host.
- *
- * @throws IllegalArgumentException if the task is not present on the host.
- */
- void start(Task task);
-
- /**
- * Stop the task if it is currently running on this host.
- *
- * @throws IllegalArgumentException if the task is not present on the host.
- */
- void stop(Task task);
-
- /**
- * Delete the specified <code>task</code> on this host and cleanup all resources associated with it.
- */
- void delete(Task task);
-
- /**
- * Add a [HostListener] to this host.
- */
- void addListener(HostListener listener);
-
- /**
- * Remove a [HostListener] from this host.
- */
- void removeListener(HostListener listener);
-
- /**
- * Query the system statistics of the host.
- */
- HostSystemStats getSystemStats();
-
- /**
- * Query the system statistics of a {@link Task} that is located on this host.
- *
- * @param task The {@link Task} to obtain the system statistics of.
- * @throws IllegalArgumentException if the task is not present on the host.
- */
- GuestSystemStats getSystemStats(Task task);
-
- /**
- * Query the CPU statistics of the host.
- */
- HostCpuStats getCpuStats();
-
- /**
- * Query the CPU statistics of a {@link Task} that is located on this host.
- *
- * @param task The {@link Task} to obtain the CPU statistics of.
- * @throws IllegalArgumentException if the task is not present on the host.
- */
- GuestCpuStats getCpuStats(Task task);
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
deleted file mode 100644
index eb686faf..00000000
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt
+++ /dev/null
@@ -1,386 +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.service
-
-import io.mockk.coEvery
-import io.mockk.coVerify
-import io.mockk.every
-import io.mockk.mockk
-import io.mockk.slot
-import io.mockk.verify
-import kotlinx.coroutines.delay
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNull
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import org.opendc.compute.api.Flavor
-import org.opendc.compute.api.Image
-import org.opendc.compute.api.Task
-import org.opendc.compute.api.TaskState
-import org.opendc.compute.api.TaskWatcher
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.driver.HostListener
-import org.opendc.compute.service.driver.HostModel
-import org.opendc.compute.service.driver.HostState
-import org.opendc.compute.service.scheduler.FilterScheduler
-import org.opendc.compute.service.scheduler.filters.ComputeFilter
-import org.opendc.compute.service.scheduler.filters.RamFilter
-import org.opendc.compute.service.scheduler.filters.VCpuFilter
-import org.opendc.compute.service.scheduler.weights.RamWeigher
-import org.opendc.simulator.kotlin.SimulationCoroutineScope
-import org.opendc.simulator.kotlin.runSimulation
-import java.time.Duration
-import java.util.UUID
-
-/**
- * Test suite for the [ComputeService] interface.
- */
-internal class ComputeServiceTest {
- private lateinit var scope: SimulationCoroutineScope
- private lateinit var service: ComputeService
-
- @BeforeEach
- fun setUp() {
- scope = SimulationCoroutineScope()
- val computeScheduler =
- FilterScheduler(
- filters = listOf(ComputeFilter(), VCpuFilter(allocationRatio = 1.0), RamFilter(allocationRatio = 1.0)),
- weighers = listOf(RamWeigher()),
- )
- service = ComputeService(scope.dispatcher, computeScheduler, Duration.ofMinutes(5), 10)
- }
-
- @Test
- fun testClientClose() =
- scope.runSimulation {
- val client = service.newClient()
-
- assertEquals(emptyList<Flavor>(), client.queryFlavors())
- assertEquals(emptyList<Image>(), client.queryImages())
- assertEquals(emptyList<Task>(), client.queryTasks())
-
- client.close()
-
- assertThrows<IllegalStateException> { client.queryFlavors() }
- assertThrows<IllegalStateException> { client.queryImages() }
- assertThrows<IllegalStateException> { client.queryTasks() }
-
- assertThrows<IllegalStateException> { client.findFlavor(UUID.randomUUID()) }
- assertThrows<IllegalStateException> { client.findImage(UUID.randomUUID()) }
- assertThrows<IllegalStateException> { client.findTask(UUID.randomUUID()) }
-
- assertThrows<IllegalStateException> { client.newFlavor("test", 1, 2) }
- assertThrows<IllegalStateException> { client.newImage("test") }
- assertThrows<IllegalStateException> { client.newTask("test", mockk(), mockk()) }
- }
-
- @Test
- fun testClientCreate() =
- scope.runSimulation {
- val client = service.newClient()
-
- val flavor = client.newFlavor("test", 1, 1024)
- assertEquals(listOf(flavor), client.queryFlavors())
- assertEquals(flavor, client.findFlavor(flavor.uid))
- val image = client.newImage("test")
- assertEquals(listOf(image), client.queryImages())
- assertEquals(image, client.findImage(image.uid))
- val server = client.newTask("test", image, flavor, start = false)
- assertEquals(listOf(server), client.queryTasks())
- assertEquals(server, client.findTask(server.uid))
-
- server.delete()
- assertNull(client.findTask(server.uid))
-
- image.delete()
- assertNull(client.findImage(image.uid))
-
- flavor.delete()
- assertNull(client.findFlavor(flavor.uid))
-
- assertThrows<IllegalStateException> { server.start() }
- }
-
- @Test
- fun testClientOnClose() =
- scope.runSimulation {
- service.close()
- assertThrows<IllegalStateException> {
- service.newClient()
- }
- }
-
- @Test
- fun testAddHost() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
-
- assertEquals(emptySet<Host>(), service.hosts)
-
- service.addHost(host)
-
- verify(exactly = 1) { host.addListener(any()) }
-
- assertEquals(1, service.hosts.size)
-
- service.removeHost(host)
-
- verify(exactly = 1) { host.removeListener(any()) }
- }
-
- @Test
- fun testAddHostDouble() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.DOWN
-
- assertEquals(emptySet<Host>(), service.hosts)
-
- service.addHost(host)
- service.addHost(host)
-
- verify(exactly = 1) { host.addListener(any()) }
- }
-
- @Test
- fun testServerStartWithoutEnoughCpus() =
- scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 0)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testServerStartWithoutEnoughMemory() =
- scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 0, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testServerStartWithoutEnoughResources() =
- scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testServerCancelRequest() =
- scope.runSimulation {
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- server.stop()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testServerCannotFitOnHost() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
-
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns false
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(10L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.PROVISIONING, server.state)
-
- verify { host.canFit(server) }
- }
-
- @Test
- fun testHostAvailableAfterSomeTime() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.DOWN
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- every { host.canFit(any()) } returns false
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
-
- every { host.state } returns HostState.UP
- listeners.forEach { it.onStateChanged(host, HostState.UP) }
-
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.PROVISIONING, server.state)
-
- verify { host.canFit(server) }
- }
-
- @Test
- fun testHostUnavailableAfterSomeTime() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- every { host.canFit(any()) } returns false
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- delay(5L * 60 * 1000)
-
- every { host.state } returns HostState.DOWN
- listeners.forEach { it.onStateChanged(host, HostState.DOWN) }
-
- server.start()
- delay(5L * 60 * 1000)
- server.reload()
- assertEquals(TaskState.PROVISIONING, server.state)
-
- verify(exactly = 0) { host.canFit(server) }
- }
-
- @Test
- fun testServerDeploy() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns true
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
- val slot = slot<Task>()
-
- val watcher = mockk<TaskWatcher>(relaxUnitFun = true)
- server.watch(watcher)
-
- // Start server
- server.start()
- delay(5L * 60 * 1000)
- coVerify { host.spawn(capture(slot)) }
-
- listeners.forEach { it.onStateChanged(host, slot.captured, TaskState.RUNNING) }
-
- server.reload()
- assertEquals(TaskState.RUNNING, server.state)
-
- verify { watcher.onStateChanged(server, TaskState.RUNNING) }
-
- // Stop server
- listeners.forEach { it.onStateChanged(host, slot.captured, TaskState.TERMINATED) }
-
- server.reload()
- assertEquals(TaskState.TERMINATED, server.state)
-
- verify { watcher.onStateChanged(server, TaskState.TERMINATED) }
- }
-
- @Test
- fun testServerDeployFailure() =
- scope.runSimulation {
- val host = mockk<Host>(relaxUnitFun = true)
- val listeners = mutableListOf<HostListener>()
-
- every { host.uid } returns UUID.randomUUID()
- every { host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.state } returns HostState.UP
- every { host.canFit(any()) } returns true
- every { host.addListener(any()) } answers { listeners.add(it.invocation.args[0] as HostListener) }
- coEvery { host.spawn(any()) } throws IllegalStateException()
-
- service.addHost(host)
-
- val client = service.newClient()
- val flavor = client.newFlavor("test", 1, 1024)
- val image = client.newImage("test")
- val server = client.newTask("test", image, flavor, start = false)
-
- server.start()
- delay(5L * 60 * 1000)
-
- server.reload()
- assertEquals(TaskState.PROVISIONING, server.state)
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceFlavorTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceFlavorTest.kt
deleted file mode 100644
index 7938f789..00000000
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceFlavorTest.kt
+++ /dev/null
@@ -1,67 +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.service
-
-import io.mockk.every
-import io.mockk.mockk
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Test
-import org.opendc.compute.api.Flavor
-import java.util.UUID
-
-/**
- * Test suite for the [ServiceFlavor] implementation.
- */
-class ServiceFlavorTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf<String, Any>())
- val b = ServiceFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf<String, Any>())
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf<String, Any>())
-
- val b = mockk<Flavor>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceFlavor(service, uid, "test", 1, 1024, mutableMapOf(), mutableMapOf<String, Any>())
-
- assertNotEquals(a, Unit)
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceImageTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceImageTest.kt
deleted file mode 100644
index c36d75f4..00000000
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceImageTest.kt
+++ /dev/null
@@ -1,67 +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.service
-
-import io.mockk.every
-import io.mockk.mockk
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Test
-import org.opendc.compute.api.Image
-import java.util.UUID
-
-/**
- * Test suite for the [ServiceFlavor] implementation.
- */
-class ServiceImageTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceImage(service, uid, "test", mutableMapOf(), mutableMapOf<String, Any>())
- val b = ServiceImage(service, uid, "test", mutableMapOf(), mutableMapOf<String, Any>())
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceImage(service, uid, "test", mutableMapOf(), mutableMapOf<String, Any>())
-
- val b = mockk<Image>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val a = ServiceImage(service, uid, "test", mutableMapOf(), mutableMapOf<String, Any>())
-
- assertNotEquals(a, Unit)
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceTaskTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceTaskTest.kt
deleted file mode 100644
index e77665fe..00000000
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ServiceTaskTest.kt
+++ /dev/null
@@ -1,442 +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.service
-
-import io.mockk.every
-import io.mockk.mockk
-import io.mockk.verify
-import kotlinx.coroutines.yield
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import org.opendc.compute.api.Task
-import org.opendc.compute.api.TaskState
-import org.opendc.compute.service.driver.Host
-import org.opendc.simulator.kotlin.runSimulation
-import java.util.UUID
-
-/**
- * Test suite for the [ServiceTask] implementation.
- */
-class ServiceTaskTest {
- @Test
- fun testEquality() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
-
- val a =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
- val b =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- assertEquals(a, b)
- }
-
- @Test
- fun testInequalityWithDifferentType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val a =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- val b = mockk<Task>(relaxUnitFun = true)
- every { b.uid } returns UUID.randomUUID()
-
- assertNotEquals(a, b)
- }
-
- @Test
- fun testInequalityWithIncorrectType() {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val a =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- assertNotEquals(a, Unit)
- }
-
- @Test
- fun testStartTerminatedServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- every { service.schedule(any()) } answers { ComputeService.SchedulingRequest(it.invocation.args[0] as ServiceTask, 0) }
-
- server.start()
-
- verify(exactly = 1) { service.schedule(server) }
- assertEquals(TaskState.PROVISIONING, server.state)
- }
-
- @Test
- fun testStartDeletedServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.DELETED)
-
- assertThrows<IllegalStateException> { server.start() }
- }
-
- @Test
- fun testStartProvisioningServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.PROVISIONING)
-
- server.start()
-
- assertEquals(TaskState.PROVISIONING, server.state)
- }
-
- @Test
- fun testStartRunningServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.RUNNING)
-
- server.start()
-
- assertEquals(TaskState.RUNNING, server.state)
- }
-
- @Test
- fun testStopProvisioningServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
- val request = ComputeService.SchedulingRequest(server, 0)
-
- every { service.schedule(any()) } returns request
-
- server.start()
- server.stop()
-
- assertTrue(request.isCancelled)
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testStopTerminatedServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.TERMINATED)
- server.stop()
-
- assertEquals(TaskState.TERMINATED, server.state)
- }
-
- @Test
- fun testStopDeletedServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.DELETED)
- server.stop()
-
- assertEquals(TaskState.DELETED, server.state)
- }
-
- @Test
- fun testStopRunningServer() =
- runSimulation {
- val service = mockk<ComputeService>()
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
- val host = mockk<Host>(relaxUnitFun = true)
-
- server.setState(TaskState.RUNNING)
- server.host = host
- server.stop()
- yield()
-
- verify { host.stop(server) }
- }
-
- @Test
- fun testDeleteProvisioningServer() =
- runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
- val request = ComputeService.SchedulingRequest(server, 0)
-
- every { service.schedule(any()) } returns request
-
- server.start()
- server.delete()
-
- assertTrue(request.isCancelled)
- assertEquals(TaskState.DELETED, server.state)
- verify { service.delete(server) }
- }
-
- @Test
- fun testDeleteTerminatedServer() =
- runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.TERMINATED)
- server.delete()
-
- assertEquals(TaskState.DELETED, server.state)
-
- verify { service.delete(server) }
- }
-
- @Test
- fun testDeleteDeletedServer() =
- runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
-
- server.setState(TaskState.DELETED)
- server.delete()
-
- assertEquals(TaskState.DELETED, server.state)
- }
-
- @Test
- fun testDeleteRunningServer() =
- runSimulation {
- val service = mockk<ComputeService>(relaxUnitFun = true)
- val uid = UUID.randomUUID()
- val flavor = mockFlavor()
- val image = mockImage()
- val server =
- ServiceTask(
- service,
- uid,
- "test",
- flavor,
- image,
- mutableMapOf(),
- mutableMapOf<String, Any>(),
- )
- val host = mockk<Host>(relaxUnitFun = true)
-
- server.setState(TaskState.RUNNING)
- server.host = host
- server.delete()
- yield()
-
- verify { host.delete(server) }
- verify { service.delete(server) }
- }
-
- private fun mockFlavor(): ServiceFlavor {
- val flavor = mockk<ServiceFlavor>()
- every { flavor.name } returns "c5.large"
- every { flavor.uid } returns UUID.randomUUID()
- every { flavor.coreCount } returns 2
- every { flavor.memorySize } returns 4096
- return flavor
- }
-
- private fun mockImage(): ServiceImage {
- val image = mockk<ServiceImage>()
- every { image.name } returns "ubuntu-20.04"
- every { image.uid } returns UUID.randomUUID()
- return image
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt b/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt
deleted file mode 100644
index add10f8f..00000000
--- a/opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/scheduler/FilterSchedulerTest.kt
+++ /dev/null
@@ -1,536 +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.service.scheduler
-
-import io.mockk.every
-import io.mockk.mockk
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNull
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertAll
-import org.junit.jupiter.api.assertThrows
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
-import org.opendc.compute.service.driver.HostModel
-import org.opendc.compute.service.driver.HostState
-import org.opendc.compute.service.scheduler.filters.ComputeFilter
-import org.opendc.compute.service.scheduler.filters.DifferentHostFilter
-import org.opendc.compute.service.scheduler.filters.InstanceCountFilter
-import org.opendc.compute.service.scheduler.filters.RamFilter
-import org.opendc.compute.service.scheduler.filters.SameHostFilter
-import org.opendc.compute.service.scheduler.filters.VCpuCapacityFilter
-import org.opendc.compute.service.scheduler.filters.VCpuFilter
-import org.opendc.compute.service.scheduler.weights.CoreRamWeigher
-import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher
-import org.opendc.compute.service.scheduler.weights.RamWeigher
-import org.opendc.compute.service.scheduler.weights.VCpuWeigher
-import java.util.Random
-import java.util.UUID
-
-/**
- * Test suite for the [FilterScheduler].
- */
-internal class FilterSchedulerTest {
- @Test
- fun testInvalidSubsetSize() {
- assertThrows<IllegalArgumentException> {
- FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- subsetSize = 0,
- )
- }
-
- assertThrows<IllegalArgumentException> {
- FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- subsetSize = -2,
- )
- }
- }
-
- @Test
- fun testNoHosts() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- )
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertNull(scheduler.select(task))
- }
-
- @Test
- fun testNoFiltersAndSchedulers() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.DOWN
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- // Make sure we get the first host both times
- assertAll(
- { assertEquals(hostA, scheduler.select(task)) },
- { assertEquals(hostA, scheduler.select(task)) },
- )
- }
-
- @Test
- fun testNoFiltersAndSchedulersRandom() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = emptyList(),
- subsetSize = Int.MAX_VALUE,
- random = Random(1),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.DOWN
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- // Make sure we get the first host both times
- assertAll(
- { assertEquals(hostB, scheduler.select(task)) },
- { assertEquals(hostA, scheduler.select(task)) },
- )
- }
-
- @Test
- fun testHostIsDown() {
- val scheduler =
- FilterScheduler(
- filters = listOf(ComputeFilter()),
- weighers = emptyList(),
- )
-
- val host = mockk<HostView>()
- every { host.host.state } returns HostState.DOWN
-
- scheduler.addHost(host)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertNull(scheduler.select(task))
- }
-
- @Test
- fun testHostIsUp() {
- val scheduler =
- FilterScheduler(
- filters = listOf(ComputeFilter()),
- weighers = emptyList(),
- )
-
- val host = mockk<HostView>()
- every { host.host.state } returns HostState.UP
-
- scheduler.addHost(host)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(host, scheduler.select(task))
- }
-
- @Test
- fun testRamFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(RamFilter(1.0)),
- weighers = emptyList(),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.availableMemory } returns 512
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.availableMemory } returns 2048
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testRamFilterOvercommit() {
- val scheduler =
- FilterScheduler(
- filters = listOf(RamFilter(1.5)),
- weighers = emptyList(),
- )
-
- val host = mockk<HostView>()
- every { host.host.state } returns HostState.UP
- every { host.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.availableMemory } returns 2048
-
- scheduler.addHost(host)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 2300
-
- assertNull(scheduler.select(task))
- }
-
- @Test
- fun testVCpuFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(VCpuFilter(1.0)),
- weighers = emptyList(),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.provisionedCores } returns 3
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.provisionedCores } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testVCpuFilterOvercommit() {
- val scheduler =
- FilterScheduler(
- filters = listOf(VCpuFilter(16.0)),
- weighers = emptyList(),
- )
-
- val host = mockk<HostView>()
- every { host.host.state } returns HostState.UP
- every { host.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { host.provisionedCores } returns 0
-
- scheduler.addHost(host)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 8
- every { task.flavor.memorySize } returns 1024
-
- assertNull(scheduler.select(task))
- }
-
-// TODO: fix when schedulers are reworked
-// @Test
- fun testVCpuCapacityFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(VCpuCapacityFilter()),
- weighers = emptyList(),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(8 * 2600.0, 8, 2048)
- every { hostA.availableMemory } returns 512
- scheduler.addHost(hostA)
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 3200.0, 4, 2048)
- every { hostB.availableMemory } returns 512
-
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
- every { task.flavor.meta } returns mapOf("cpu-capacity" to 2 * 3200.0)
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testInstanceCountFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(InstanceCountFilter(limit = 2)),
- weighers = emptyList(),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.instanceCount } returns 2
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.instanceCount } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testAffinityFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(SameHostFilter()),
- weighers = emptyList(),
- )
-
- val taskA = mockk<Task>()
- every { taskA.uid } returns UUID.randomUUID()
- every { taskA.flavor.coreCount } returns 2
- every { taskA.flavor.memorySize } returns 1024
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.host.instances } returns emptySet()
- every { hostA.provisionedCores } returns 3
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.host.instances } returns setOf(taskA)
- every { hostB.provisionedCores } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val taskB = mockk<Task>()
- every { taskB.flavor.coreCount } returns 2
- every { taskB.flavor.memorySize } returns 1024
- every { taskB.meta } returns emptyMap()
-
- assertEquals(hostA, scheduler.select(taskB))
-
- every { taskB.meta } returns mapOf("scheduler_hint:same_host" to setOf(taskA.uid))
-
- assertEquals(hostB, scheduler.select(taskB))
- }
-
- @Test
- fun testAntiAffinityFilter() {
- val scheduler =
- FilterScheduler(
- filters = listOf(DifferentHostFilter()),
- weighers = emptyList(),
- )
-
- val taskA = mockk<Task>()
- every { taskA.uid } returns UUID.randomUUID()
- every { taskA.flavor.coreCount } returns 2
- every { taskA.flavor.memorySize } returns 1024
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.host.instances } returns setOf(taskA)
- every { hostA.provisionedCores } returns 3
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.host.instances } returns emptySet()
- every { hostB.provisionedCores } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val taskB = mockk<Task>()
- every { taskB.flavor.coreCount } returns 2
- every { taskB.flavor.memorySize } returns 1024
- every { taskB.meta } returns emptyMap()
-
- assertEquals(hostA, scheduler.select(taskB))
-
- every { taskB.meta } returns mapOf("scheduler_hint:different_host" to setOf(taskA.uid))
-
- assertEquals(hostB, scheduler.select(taskB))
- }
-
- @Test
- fun testRamWeigher() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = listOf(RamWeigher(1.5)),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.availableMemory } returns 1024
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.availableMemory } returns 512
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostA, scheduler.select(task))
- }
-
- // TODO: fix test when updating schedulers
-// @Test
- fun testCoreRamWeigher() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = listOf(CoreRamWeigher(1.5)),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(12 * 2600.0, 12, 2048)
- every { hostA.availableMemory } returns 1024
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.availableMemory } returns 512
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testVCpuWeigher() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = listOf(VCpuWeigher(16.0)),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.provisionedCores } returns 2
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.provisionedCores } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-
- @Test
- fun testInstanceCountWeigher() {
- val scheduler =
- FilterScheduler(
- filters = emptyList(),
- weighers = listOf(InstanceCountWeigher(multiplier = -1.0)),
- )
-
- val hostA = mockk<HostView>()
- every { hostA.host.state } returns HostState.UP
- every { hostA.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostA.instanceCount } returns 2
-
- val hostB = mockk<HostView>()
- every { hostB.host.state } returns HostState.UP
- every { hostB.host.model } returns HostModel(4 * 2600.0, 4, 2048)
- every { hostB.instanceCount } returns 0
-
- scheduler.addHost(hostA)
- scheduler.addHost(hostB)
-
- val task = mockk<Task>()
- every { task.flavor.coreCount } returns 2
- every { task.flavor.memorySize } returns 1024
-
- assertEquals(hostB, scheduler.select(task))
- }
-}
diff --git a/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml b/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml
deleted file mode 100644
index 0dfb75f2..00000000
--- a/opendc-compute/opendc-compute-service/src/test/resources/log4j2.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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-simulator/build.gradle.kts b/opendc-compute/opendc-compute-simulator/build.gradle.kts
index 20ceb93e..8cbddb44 100644
--- a/opendc-compute/opendc-compute-simulator/build.gradle.kts
+++ b/opendc-compute/opendc-compute-simulator/build.gradle.kts
@@ -25,22 +25,25 @@ description = "Simulator for OpenDC Compute"
// Build configuration
plugins {
`kotlin-library-conventions`
+ kotlin("plugin.serialization") version "1.9.22"
}
dependencies {
- api(projects.opendcCompute.opendcComputeService)
api(projects.opendcSimulator.opendcSimulatorCompute)
+ api(projects.opendcTrace.opendcTraceParquet)
api(libs.commons.math3)
implementation(projects.opendcCommon)
implementation(libs.kotlin.logging)
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
api(libs.microprofile.config)
implementation(project(mapOf("path" to ":opendc-compute:opendc-compute-topology")))
- 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")))
+ implementation(project(mapOf("path" to ":opendc-trace:opendc-trace-parquet")))
testImplementation(projects.opendcSimulator.opendcSimulatorCore)
testRuntimeOnly(libs.slf4j.simple)
+ testRuntimeOnly(libs.log4j.slf4j)
}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostListener.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/host/HostListener.java
index 079c6cff..01acfa97 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostListener.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/host/HostListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022 AtLarge Research
+ * 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
@@ -20,22 +20,22 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.driver;
+package org.opendc.compute.simulator.host;
-import org.opendc.compute.api.Task;
import org.opendc.compute.api.TaskState;
+import org.opendc.compute.simulator.service.ServiceTask;
/**
- * Listener interface for events originating from a {@link Host}.
+ * Listener interface for events originating from a {@link SimHost}.
*/
public interface HostListener {
/**
* This method is invoked when the state of <code>task</code> on <code>host</code> changes.
*/
- default void onStateChanged(Host host, Task task, TaskState newState) {}
+ default void onStateChanged(SimHost host, ServiceTask task, TaskState newState) {}
/**
- * This method is invoked when the state of a {@link Host} has changed.
+ * This method is invoked when the state of a {@link SimHost} has changed.
*/
- default void onStateChanged(Host host, HostState newState) {}
+ default void onStateChanged(SimHost host, HostState newState) {}
}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostModel.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/host/HostModel.java
index 87464fe1..96236c5c 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostModel.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/host/HostModel.java
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.driver;
+package org.opendc.compute.simulator.host;
/**
* Record describing the static machine properties of the host.
@@ -29,4 +29,4 @@ package org.opendc.compute.service.driver;
* @param coreCount The number of logical processing cores available for this host.
* @param memoryCapacity The amount of memory available for this host in MB.
*/
-public record HostModel(double cpuCapacity, int coreCount, long memoryCapacity) {}
+public record HostModel(float cpuCapacity, int coreCount, long memoryCapacity) {}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostState.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/host/HostState.java
index ce12a67e..29fc8cb4 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/HostState.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/host/HostState.java
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.driver;
+package org.opendc.compute.simulator.host;
/**
* The state of a host.
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java
index ad01ee57..84e23516 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ComputeService.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.service;
+package org.opendc.compute.simulator.service;
import java.time.Duration;
import java.time.Instant;
@@ -41,18 +41,16 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.opendc.common.Dispatcher;
import org.opendc.common.util.Pacer;
-import org.opendc.compute.api.ComputeClient;
import org.opendc.compute.api.Flavor;
import org.opendc.compute.api.Image;
-import org.opendc.compute.api.Task;
import org.opendc.compute.api.TaskState;
-import org.opendc.compute.service.driver.Host;
-import org.opendc.compute.service.driver.HostListener;
-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.opendc.compute.simulator.host.HostListener;
+import org.opendc.compute.simulator.host.HostModel;
+import org.opendc.compute.simulator.host.HostState;
+import org.opendc.compute.simulator.host.SimHost;
+import org.opendc.compute.simulator.scheduler.ComputeScheduler;
+import org.opendc.compute.simulator.telemetry.SchedulerStats;
+import org.opendc.simulator.compute.workload.Workload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -92,7 +90,7 @@ public final class ComputeService implements AutoCloseable {
/**
* A mapping from host to host view.
*/
- private final Map<Host, HostView> hostToView = new HashMap<>();
+ private final Map<SimHost, HostView> hostToView = new HashMap<>();
/**
* The available hypervisors.
@@ -107,7 +105,12 @@ public final class ComputeService implements AutoCloseable {
/**
* The active tasks in the system.
*/
- private final Map<Task, Host> activeTasks = new HashMap<>();
+ private final Map<ServiceTask, SimHost> activeTasks = new HashMap<>();
+
+ /**
+ * The active tasks in the system.
+ */
+ private final Map<ServiceTask, SimHost> completedTasks = new HashMap<>();
/**
* The registered flavors for this compute service.
@@ -130,12 +133,14 @@ public final class ComputeService implements AutoCloseable {
private final List<ServiceTask> tasks = new ArrayList<>();
+ private final List<ServiceTask> tasksToRemove = new ArrayList<>();
+
/**
* A [HostListener] used to track the active tasks.
*/
private final HostListener hostListener = new HostListener() {
@Override
- public void onStateChanged(@NotNull Host host, @NotNull HostState newState) {
+ public void onStateChanged(@NotNull SimHost host, @NotNull HostState newState) {
LOGGER.debug("Host {} state changed: {}", host, newState);
final HostView hv = hostToView.get(host);
@@ -153,19 +158,16 @@ public final class ComputeService implements AutoCloseable {
}
@Override
- public void onStateChanged(@NotNull Host host, @NotNull Task task, @NotNull TaskState newState) {
- final ServiceTask serviceTask = (ServiceTask) task;
-
- if (serviceTask.getHost() != host) {
+ public void onStateChanged(@NotNull SimHost host, @NotNull ServiceTask task, @NotNull TaskState newState) {
+ if (task.getHost() != host) {
// This can happen when a task is rescheduled and started on another machine, while being deleted from
// the old machine.
return;
}
- serviceTask.setState(newState);
+ task.setState(newState);
- // TODO: move the removal of tasks when max Failures are reached to here
- if (newState == TaskState.TERMINATED || newState == TaskState.DELETED || newState == TaskState.ERROR) {
+ if (newState == TaskState.COMPLETED || newState == TaskState.TERMINATED || newState == TaskState.FAILED) {
LOGGER.info("task {} {} {} finished", task.getUid(), task.getName(), task.getFlavor());
if (activeTasks.remove(task) != null) {
@@ -173,7 +175,7 @@ public final class ComputeService implements AutoCloseable {
}
HostView hv = hostToView.get(host);
- final ServiceFlavor flavor = serviceTask.getFlavor();
+ final ServiceFlavor flavor = task.getFlavor();
if (hv != null) {
hv.provisionedCores -= flavor.getCoreCount();
hv.instanceCount--;
@@ -182,6 +184,20 @@ public final class ComputeService implements AutoCloseable {
LOGGER.error("Unknown host {}", host);
}
+ task.setHost(null);
+ host.removeTask(task);
+
+ if (newState == TaskState.COMPLETED) {
+ tasksCompleted++;
+ }
+ if (newState == TaskState.TERMINATED) {
+ tasksTerminated++;
+ }
+
+ if (task.getState() == TaskState.COMPLETED || task.getState() == TaskState.TERMINATED) {
+ tasksToRemove.add(task);
+ }
+
// Try to reschedule if needed
requestSchedulingCycle();
}
@@ -192,14 +208,16 @@ public final class ComputeService implements AutoCloseable {
private long maxMemory = 0L;
private long attemptsSuccess = 0L;
private long attemptsFailure = 0L;
- private long attemptsError = 0L;
+ private int tasksTotal = 0;
private int tasksPending = 0;
private int tasksActive = 0;
+ private int tasksTerminated = 0;
+ private int tasksCompleted = 0;
/**
* Construct a {@link ComputeService} instance.
*/
- ComputeService(Dispatcher dispatcher, ComputeScheduler scheduler, Duration quantum, int maxNumFailures) {
+ public ComputeService(Dispatcher dispatcher, ComputeScheduler scheduler, Duration quantum, int maxNumFailures) {
this.clock = dispatcher.getTimeSource();
this.scheduler = scheduler;
this.pacer = new Pacer(dispatcher, quantum.toMillis(), (time) -> doSchedule());
@@ -220,20 +238,31 @@ public final class ComputeService implements AutoCloseable {
if (isClosed) {
throw new IllegalStateException("Service is closed");
}
- return new Client(this);
+ return new ComputeClient(this);
}
/**
- * Return the {@link Task}s hosted by this service.
+ * Return the {@link ServiceTask}s hosted by this service.
*/
- public List<Task> getTasks() {
+ public List<ServiceTask> getTasks() {
return Collections.unmodifiableList(tasks);
}
/**
- * Add a {@link Host} to the scheduling pool of the compute service.
+ * Return the {@link ServiceTask}s hosted by this service.
+ */
+ public List<ServiceTask> getTasksToRemove() {
+ return Collections.unmodifiableList(tasksToRemove);
+ }
+
+ public void clearTasksToRemove() {
+ this.tasksToRemove.clear();
+ }
+
+ /**
+ * Add a {@link SimHost} to the scheduling pool of the compute service.
*/
- public void addHost(Host host) {
+ public void addHost(SimHost host) {
// Check if host is already known
if (hostToView.containsKey(host)) {
return;
@@ -255,9 +284,9 @@ public final class ComputeService implements AutoCloseable {
}
/**
- * Remove a {@link Host} from the scheduling pool of the compute service.
+ * Remove a {@link SimHost} from the scheduling pool of the compute service.
*/
- public void removeHost(Host host) {
+ public void removeHost(SimHost host) {
HostView view = hostToView.remove(host);
if (view != null) {
availableHosts.remove(view);
@@ -267,24 +296,23 @@ public final class ComputeService implements AutoCloseable {
}
/**
- * Lookup the {@link Host} that currently hosts the specified {@link Task}.
+ * Lookup the {@link SimHost} that currently hosts the specified {@link ServiceTask}.
*/
- public Host lookupHost(Task task) {
- if (task instanceof ServiceTask) {
- return ((ServiceTask) task).getHost();
- }
-
- ServiceTask internal = Objects.requireNonNull(taskById.get(task.getUid()), "Invalid task passed to lookupHost");
- return internal.getHost();
+ public SimHost lookupHost(ServiceTask task) {
+ return task.getHost();
}
/**
- * Return the {@link Host}s that are registered with this service.
+ * Return the {@link SimHost}s that are registered with this service.
*/
- public Set<Host> getHosts() {
+ public Set<SimHost> getHosts() {
return Collections.unmodifiableSet(hostToView.keySet());
}
+ public InstantSource getClock() {
+ return this.clock;
+ }
+
/**
* Collect the statistics about the scheduler component of this service.
*/
@@ -294,10 +322,11 @@ public final class ComputeService implements AutoCloseable {
hostToView.size() - availableHosts.size(),
attemptsSuccess,
attemptsFailure,
- attemptsError,
- tasks.size(),
+ tasksTotal,
tasksPending,
- tasksActive);
+ tasksActive,
+ tasksCompleted,
+ tasksTerminated);
}
@Override
@@ -337,6 +366,7 @@ public final class ComputeService implements AutoCloseable {
}
void delete(ServiceTask task) {
+ completedTasks.remove(task);
taskById.remove(task.getUid());
tasks.remove(task);
}
@@ -370,13 +400,14 @@ public final class ComputeService implements AutoCloseable {
final ServiceTask task = request.task;
- // Remove task from scheduling if it has failed too many times
- if (task.getNumFailures() > maxNumFailures) {
- LOGGER.warn("Failed to spawn {}: Task has failed more than the allowed {} times", task, maxNumFailures);
+ if (task.getNumFailures() >= maxNumFailures) {
+ LOGGER.warn("task {} has been terminated because it failed {} times", task, task.getNumFailures());
taskQueue.poll();
tasksPending--;
+ tasksTerminated++;
task.setState(TaskState.TERMINATED);
+ tasksToRemove.add(task);
continue;
}
@@ -390,18 +421,17 @@ public final class ComputeService implements AutoCloseable {
// Remove the incoming image
taskQueue.poll();
tasksPending--;
- attemptsFailure++;
LOGGER.warn("Failed to spawn {}: does not fit", task);
- task.setState(TaskState.TERMINATED);
+ task.setState(TaskState.FAILED);
continue;
} else {
break;
}
}
- Host host = hv.getHost();
+ SimHost host = hv.getHost();
// Remove request from queue
taskQueue.poll();
@@ -413,7 +443,7 @@ public final class ComputeService implements AutoCloseable {
task.host = host;
host.spawn(task);
- host.start(task);
+ // host.start(task);
tasksActive++;
attemptsSuccess++;
@@ -425,7 +455,7 @@ public final class ComputeService implements AutoCloseable {
activeTasks.put(task, host);
} catch (Exception cause) {
LOGGER.error("Failed to deploy VM", cause);
- attemptsError++;
+ attemptsFailure++;
}
}
}
@@ -436,7 +466,7 @@ public final class ComputeService implements AutoCloseable {
public static class Builder {
private final Dispatcher dispatcher;
private final ComputeScheduler computeScheduler;
- private Duration quantum = Duration.ofMinutes(5);
+ private Duration quantum = Duration.ofSeconds(1);
private int maxNumFailures = 10;
Builder(Dispatcher dispatcher, ComputeScheduler computeScheduler) {
@@ -468,11 +498,11 @@ public final class ComputeService implements AutoCloseable {
/**
* Implementation of {@link ComputeClient} using a {@link ComputeService}.
*/
- private static class Client implements ComputeClient {
+ public static class ComputeClient {
private final ComputeService service;
private boolean isClosed;
- Client(ComputeService service) {
+ ComputeClient(ComputeService service) {
this.service = service;
}
@@ -486,13 +516,11 @@ public final class ComputeService implements AutoCloseable {
}
@NotNull
- @Override
public List<Flavor> queryFlavors() {
checkOpen();
return new ArrayList<>(service.flavors);
}
- @Override
public Flavor findFlavor(@NotNull UUID id) {
checkOpen();
@@ -500,18 +528,12 @@ public final class ComputeService implements AutoCloseable {
}
@NotNull
- @Override
- public Flavor newFlavor(
- @NotNull String name,
- int cpuCount,
- long memorySize,
- @NotNull Map<String, String> labels,
- @NotNull Map<String, ?> meta) {
+ public Flavor newFlavor(@NotNull String name, int cpuCount, long memorySize, @NotNull Map<String, ?> meta) {
checkOpen();
final ComputeService service = this.service;
UUID uid = new UUID(service.clock.millis(), service.random.nextLong());
- ServiceFlavor flavor = new ServiceFlavor(service, uid, name, cpuCount, memorySize, labels, meta);
+ ServiceFlavor flavor = new ServiceFlavor(service, uid, name, cpuCount, memorySize, meta);
service.flavorById.put(uid, flavor);
service.flavors.add(flavor);
@@ -520,20 +542,22 @@ public final class ComputeService implements AutoCloseable {
}
@NotNull
- @Override
public List<Image> queryImages() {
checkOpen();
return new ArrayList<>(service.images);
}
- @Override
public Image findImage(@NotNull UUID id) {
checkOpen();
return service.imageById.get(id);
}
+ public Image newImage(@NotNull String name) {
+ return newImage(name, Collections.emptyMap(), Collections.emptyMap());
+ }
+
@NotNull
public Image newImage(@NotNull String name, @NotNull Map<String, String> labels, @NotNull Map<String, ?> meta) {
checkOpen();
@@ -550,14 +574,11 @@ public final class ComputeService implements AutoCloseable {
}
@NotNull
- @Override
- public Task newTask(
+ public ServiceTask newTask(
@NotNull String name,
- @NotNull Image image,
@NotNull Flavor flavor,
- @NotNull Map<String, String> labels,
- @NotNull Map<String, ?> meta,
- boolean start) {
+ @NotNull Workload workload,
+ @NotNull Map<String, ?> meta) {
checkOpen();
final ComputeService service = this.service;
@@ -565,37 +586,32 @@ public final class ComputeService implements AutoCloseable {
final ServiceFlavor internalFlavor =
Objects.requireNonNull(service.flavorById.get(flavor.getUid()), "Unknown flavor");
- final ServiceImage internalImage =
- Objects.requireNonNull(service.imageById.get(image.getUid()), "Unknown image");
- ServiceTask task = new ServiceTask(service, uid, name, internalFlavor, internalImage, labels, meta);
+ ServiceTask task = new ServiceTask(service, uid, name, internalFlavor, workload, meta);
service.taskById.put(uid, task);
service.tasks.add(task);
- if (start) {
- task.start();
- }
+ service.tasksTotal++;
+
+ task.start();
return task;
}
@Nullable
- @Override
- public Task findTask(@NotNull UUID id) {
+ public ServiceTask findTask(@NotNull UUID id) {
checkOpen();
return service.taskById.get(id);
}
@NotNull
- @Override
- public List<Task> queryTasks() {
+ public List<ServiceTask> queryTasks() {
checkOpen();
return new ArrayList<>(service.tasks);
}
- @Override
public void close() {
isClosed = true;
}
@@ -606,12 +622,11 @@ public final class ComputeService implements AutoCloseable {
}
@Nullable
- @Override
- public void rescheduleTask(@NotNull Task task, @NotNull SimWorkload workload) {
- ServiceTask internalTask = (ServiceTask) findTask(task.getUid());
- Host from = service.lookupHost(internalTask);
+ public void rescheduleTask(@NotNull ServiceTask task, @NotNull Workload workload) {
+ ServiceTask internalTask = findTask(task.getUid());
+ // SimHost from = service.lookupHost(internalTask);
- from.delete(internalTask);
+ // from.delete(internalTask);
internalTask.host = null;
@@ -621,7 +636,7 @@ public final class ComputeService implements AutoCloseable {
}
/**
- * A request to schedule a {@link ServiceTask} onto one of the {@link Host}s.
+ * A request to schedule a {@link ServiceTask} onto one of the {@link SimHost}s.
*/
static class SchedulingRequest {
final ServiceTask task;
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/HostView.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/HostView.java
index 6e2cdcb4..f4aa9c70 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/HostView.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/HostView.java
@@ -20,15 +20,15 @@
* SOFTWARE.
*/
-package org.opendc.compute.service;
+package org.opendc.compute.simulator.service;
-import org.opendc.compute.service.driver.Host;
+import org.opendc.compute.simulator.host.SimHost;
/**
- * A view of a {@link Host} as seen from the {@link ComputeService}.
+ * A view of a {@link SimHost} as seen from the {@link ComputeService}.
*/
public class HostView {
- private final Host host;
+ private final SimHost host;
int instanceCount;
long availableMemory;
int provisionedCores;
@@ -38,15 +38,15 @@ public class HostView {
*
* @param host The host to create a view of.
*/
- public HostView(Host host) {
+ public HostView(SimHost host) {
this.host = host;
this.availableMemory = host.getModel().memoryCapacity();
}
/**
- * The {@link Host} this is a view of.
+ * The {@link SimHost} this is a view of.
*/
- public Host getHost() {
+ public SimHost getHost() {
return host;
}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceFlavor.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceFlavor.java
index 0f434a6a..eddde87e 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceFlavor.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceFlavor.java
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.service;
+package org.opendc.compute.simulator.service;
import java.util.Collections;
import java.util.Map;
@@ -38,23 +38,14 @@ public final class ServiceFlavor implements Flavor {
private final String name;
private final int coreCount;
private final long memorySize;
- private final Map<String, String> labels;
private final Map<String, ?> meta;
- ServiceFlavor(
- ComputeService service,
- UUID uid,
- String name,
- int coreCount,
- long memorySize,
- Map<String, String> labels,
- Map<String, ?> meta) {
+ ServiceFlavor(ComputeService service, UUID uid, String name, int coreCount, long memorySize, Map<String, ?> meta) {
this.service = service;
this.uid = uid;
this.name = name;
this.coreCount = coreCount;
this.memorySize = memorySize;
- this.labels = labels;
this.meta = meta;
}
@@ -82,12 +73,6 @@ public final class ServiceFlavor implements Flavor {
@NotNull
@Override
- public Map<String, String> getLabels() {
- return Collections.unmodifiableMap(labels);
- }
-
- @NotNull
- @Override
public Map<String, Object> getMeta() {
return Collections.unmodifiableMap(meta);
}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceImage.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceImage.java
index 706be483..dffa4356 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceImage.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceImage.java
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.service;
+package org.opendc.compute.simulator.service;
import java.util.Collections;
import java.util.Map;
@@ -61,12 +61,6 @@ public final class ServiceImage implements Image {
@NotNull
@Override
- public Map<String, String> getLabels() {
- return Collections.unmodifiableMap(labels);
- }
-
- @NotNull
- @Override
public Map<String, Object> getMeta() {
return Collections.unmodifiableMap(meta);
}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceTask.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceTask.java
index f0e2a82e..f39142eb 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/ServiceTask.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ServiceTask.java
@@ -20,29 +20,28 @@
* SOFTWARE.
*/
-package org.opendc.compute.service;
+package org.opendc.compute.simulator.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;
import java.util.UUID;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.opendc.compute.api.Task;
import org.opendc.compute.api.TaskState;
-import org.opendc.compute.api.TaskWatcher;
-import org.opendc.compute.service.driver.Host;
+import org.opendc.compute.simulator.TaskWatcher;
+import org.opendc.compute.simulator.host.SimHost;
+import org.opendc.simulator.compute.workload.Workload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Implementation of {@link Task} provided by {@link ComputeService}.
+ * Implementation of {@link ServiceTask} provided by {@link ComputeService}.
*/
-public final class ServiceTask implements Task {
+public class ServiceTask {
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceTask.class);
private final ComputeService service;
@@ -50,14 +49,16 @@ public final class ServiceTask implements Task {
private final String name;
private final ServiceFlavor flavor;
- private final ServiceImage image;
- private final Map<String, String> labels;
- private Map<String, ?> meta;
+ public Workload workload;
+
+ private Map<String, ?> meta; // TODO: remove this
private final List<TaskWatcher> watchers = new ArrayList<>();
- private TaskState state = TaskState.TERMINATED;
+ private TaskState state = TaskState.CREATED;
Instant launchedAt = null;
- Host host = null;
+ Instant createdAt;
+ Instant finishedAt;
+ SimHost host = null;
private ComputeService.SchedulingRequest request = null;
private int numFailures = 0;
@@ -67,81 +68,77 @@ public final class ServiceTask implements Task {
UUID uid,
String name,
ServiceFlavor flavor,
- ServiceImage image,
- Map<String, String> labels,
+ Workload workload,
Map<String, ?> meta) {
this.service = service;
this.uid = uid;
this.name = name;
this.flavor = flavor;
- this.image = image;
- this.labels = labels;
+ this.workload = workload;
this.meta = meta;
+
+ this.createdAt = this.service.getClock().instant();
}
@NotNull
- @Override
public UUID getUid() {
return uid;
}
@NotNull
- @Override
public String getName() {
return name;
}
@NotNull
- @Override
public ServiceFlavor getFlavor() {
return flavor;
}
@NotNull
- @Override
- public ServiceImage getImage() {
- return image;
- }
-
- @NotNull
- @Override
- public Map<String, String> getLabels() {
- return Collections.unmodifiableMap(labels);
- }
-
- @NotNull
- @Override
public Map<String, Object> getMeta() {
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;
+ public void setWorkload(Workload newWorkload) {
+ this.workload = newWorkload;
}
@NotNull
- @Override
public TaskState getState() {
return state;
}
@Nullable
- @Override
public Instant getLaunchedAt() {
return launchedAt;
}
+ @Nullable
+ public Instant getCreatedAt() {
+ return createdAt;
+ }
+
+ @Nullable
+ public Instant getFinishedAt() {
+ return finishedAt;
+ }
+
/**
- * Return the {@link Host} on which the task is running or <code>null</code> if it is not running on a host.
+ * Return the {@link SimHost} on which the task is running or <code>null</code> if it is not running on a host.
*/
- public Host getHost() {
+ public SimHost getHost() {
return host;
}
- @Override
+ public void setHost(SimHost host) {
+ this.host = host;
+ }
+
+ public int getNumFailures() {
+ return this.numFailures;
+ }
+
public void start() {
switch (state) {
case PROVISIONING:
@@ -149,74 +146,43 @@ public final class ServiceTask implements Task {
case RUNNING:
LOGGER.debug("User tried to start task but task is already running");
break;
- case DELETED:
+ case COMPLETED:
+ case TERMINATED:
LOGGER.warn("User tried to start deleted task");
throw new IllegalStateException("Task is deleted");
- default:
+ case CREATED:
LOGGER.info("User requested to start task {}", uid);
setState(TaskState.PROVISIONING);
assert request == null : "Scheduling request already active";
request = service.schedule(this);
break;
- }
- }
-
- @Override
- public void stop() {
- switch (state) {
- case PROVISIONING:
- cancelProvisioningRequest();
- setState(TaskState.TERMINATED);
- break;
- case RUNNING:
- case ERROR:
- final Host host = this.host;
- if (host == null) {
- throw new IllegalStateException("Task not running");
- }
- host.stop(this);
+ case FAILED:
+ LOGGER.info("User requested to start task after failure {}", uid);
+ setState(TaskState.PROVISIONING);
+ request = service.schedule(this);
break;
}
}
- @Override
public void watch(@NotNull TaskWatcher watcher) {
watchers.add(watcher);
}
- @Override
public void unwatch(@NotNull TaskWatcher watcher) {
watchers.remove(watcher);
}
- @Override
- public void reload() {
- // No-op: this object is the source-of-truth
- }
-
- @Override
public void delete() {
- switch (state) {
- case PROVISIONING:
- case TERMINATED:
- cancelProvisioningRequest();
- service.delete(this);
- setState(TaskState.DELETED);
- break;
- case RUNNING:
- case ERROR:
- final Host host = this.host;
- if (host == null) {
- throw new IllegalStateException("Task not running");
- }
- host.delete(this);
- service.delete(this);
- setState(TaskState.DELETED);
- break;
+ cancelProvisioningRequest();
+ final SimHost host = this.host;
+ if (host != null) {
+ host.delete(this);
}
+ service.delete(this);
+
+ this.setState(TaskState.DELETED);
}
- @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -224,12 +190,10 @@ public final class ServiceTask implements Task {
return service.equals(task.service) && uid.equals(task.uid);
}
- @Override
public int hashCode() {
return Objects.hash(service, uid);
}
- @Override
public String toString() {
return "Task[uid=" + uid + ",name=" + name + ",state=" + state + "]";
}
@@ -242,10 +206,14 @@ public final class ServiceTask implements Task {
for (TaskWatcher watcher : watchers) {
watcher.onStateChanged(this, newState);
}
- if (newState == TaskState.ERROR) {
+ if (newState == TaskState.FAILED) {
this.numFailures++;
}
+ if ((newState == TaskState.COMPLETED) || newState == TaskState.FAILED) {
+ this.finishedAt = this.service.getClock().instant();
+ }
+
this.state = newState;
}
@@ -259,9 +227,4 @@ public final class ServiceTask implements Task {
request.isCancelled = true;
}
}
-
- @Override
- public int getNumFailures() {
- return this.numFailures;
- }
}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestCpuStats.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/GuestCpuStats.java
index 0b78c7ea..ea37f5f2 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestCpuStats.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/GuestCpuStats.java
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.driver.telemetry;
+package org.opendc.compute.simulator.telemetry;
/**
* Statistics about the CPUs of a guest.
@@ -38,6 +38,6 @@ public record GuestCpuStats(
long idleTime,
long stealTime,
long lostTime,
- double capacity,
- double usage,
- double utilization) {}
+ float capacity,
+ float usage,
+ float utilization) {}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestSystemStats.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/GuestSystemStats.java
index dbf98dd5..0d51e223 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/GuestSystemStats.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/GuestSystemStats.java
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.driver.telemetry;
+package org.opendc.compute.simulator.telemetry;
import java.time.Duration;
import java.time.Instant;
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostCpuStats.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/HostCpuStats.java
index d1c2328b..3f2aab78 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostCpuStats.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/HostCpuStats.java
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.driver.telemetry;
+package org.opendc.compute.simulator.telemetry;
/**
* Statistics about the CPUs of a host.
@@ -40,7 +40,7 @@ public record HostCpuStats(
long idleTime,
long stealTime,
long lostTime,
- double capacity,
- double demand,
- double usage,
- double utilization) {}
+ float capacity,
+ float demand,
+ float usage,
+ float utilization) {}
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostSystemStats.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/HostSystemStats.java
index c0713f3c..353e62fa 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/driver/telemetry/HostSystemStats.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/HostSystemStats.java
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.driver.telemetry;
+package org.opendc.compute.simulator.telemetry;
import java.time.Duration;
import java.time.Instant;
@@ -42,8 +42,8 @@ public record HostSystemStats(
Duration uptime,
Duration downtime,
Instant bootTime,
- double powerDraw,
- double energyUsage,
+ float powerDraw,
+ float energyUsage,
int guestsTerminated,
int guestsRunning,
int guestsError,
diff --git a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/telemetry/SchedulerStats.java b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/SchedulerStats.java
index fc044d8c..9d44a4b8 100644
--- a/opendc-compute/opendc-compute-service/src/main/java/org/opendc/compute/service/telemetry/SchedulerStats.java
+++ b/opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/telemetry/SchedulerStats.java
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.telemetry;
+package org.opendc.compute.simulator.telemetry;
/**
* Statistics about the scheduling component of the [ComputeService].
@@ -28,8 +28,7 @@ package org.opendc.compute.service.telemetry;
* @param hostsAvailable The number of hosts currently available for scheduling.
* @param hostsUnavailable The number of hosts unavailable for scheduling.
* @param attemptsSuccess Scheduling attempts that resulted into an allocation onto a host.
- * @param attemptsFailure The number of failed scheduling attempt due to insufficient capacity at the moment.
- * @param attemptsError The number of scheduling attempts that failed due to system error.
+ * @param attemptsFailure The number of failed scheduling attempt due to any reason
* @param tasksTotal The number of tasks registered with the service.
* @param tasksPending The number of tasks that are pending to be scheduled.
* @param tasksActive The number of tasks that are currently managed by the service and running.
@@ -39,7 +38,8 @@ public record SchedulerStats(
int hostsUnavailable,
long attemptsSuccess,
long attemptsFailure,
- long attemptsError,
int tasksTotal,
int tasksPending,
- int tasksActive) {}
+ int tasksActive,
+ int tasksCompleted,
+ int tasksTerminated) {}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/MutableServiceRegistry.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/MutableServiceRegistry.kt
deleted file mode 100644
index ca72c910..00000000
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/MutableServiceRegistry.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2022 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
-
-/**
- * A mutable [ServiceRegistry].
- */
-public interface MutableServiceRegistry : ServiceRegistry {
- /**
- * Register [service] for the specified [name] in this registry.
- *
- * @param name The name of the service to register, which should follow the rules for domain names as defined by
- * DNS.
- * @param type The interface provided by the service.
- * @param service A reference to the actual implementation of the service.
- */
- public fun <T : Any> register(
- name: String,
- type: Class<T>,
- service: T,
- )
-
- /**
- * Remove the service with [name] and [type] from this registry.
- *
- * @param name The name of the service to remove, which should follow the rules for domain names as defined by DNS.
- * @param type The type of the service to remove.
- */
- public fun remove(
- name: String,
- type: Class<*>,
- )
-
- /**
- * Remove all services registered with [name].
- *
- * @param name The name of the services to remove, which should follow the rules for domain names as defined by DNS.
- */
- public fun remove(name: String)
-
- /**
- * Create a copy of the registry.
- */
- public override fun clone(): MutableServiceRegistry
-}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistry.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistry.kt
index 5a4bced1..e2f6c9d0 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistry.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistry.kt
@@ -23,26 +23,53 @@
package org.opendc.compute.simulator
/**
- * A read-only registry of services used during experiments to resolve services.
- *
- * The service registry is similar conceptually to the Domain Name System (DNS), which is a naming system used to
- * identify computers reachable via the Internet. The service registry should be used in a similar fashion.
+ * Implementation of the [ServiceRegistry] interface.
*/
-public interface ServiceRegistry {
- /**
- * Lookup the service with the specified [name] and [type].
- *
- * @param name The name of the service to resolve, which should follow the rules for domain names as defined by DNS.
- * @param type The type of the service to resolve, identified by the interface that is implemented by the service.
- * @return The service with specified [name] and implementing [type] or `null` if it does not exist.
- */
+public class ServiceRegistry(private val registry: MutableMap<String, MutableMap<Class<*>, Any>> = mutableMapOf()) {
public fun <T : Any> resolve(
name: String,
type: Class<T>,
- ): T?
+ ): T? {
+ val servicesForName = registry[name] ?: return null
+
+ @Suppress("UNCHECKED_CAST")
+ return servicesForName[type] as T?
+ }
+
+ public fun <T : Any> register(
+ name: String,
+ type: Class<T>,
+ service: T,
+ ) {
+ val services = registry.computeIfAbsent(name) { mutableMapOf() }
+
+ if (type in services) {
+ throw IllegalStateException("Duplicate service $type registered for name $name")
+ }
+
+ services[type] = service
+ }
+
+ public fun remove(
+ name: String,
+ type: Class<*>,
+ ) {
+ val services = registry[name] ?: return
+ services.remove(type)
+ }
+
+ public fun remove(name: String) {
+ registry.remove(name)
+ }
+
+ public fun clone(): ServiceRegistry {
+ val res = mutableMapOf<String, MutableMap<Class<*>, Any>>()
+ registry.mapValuesTo(res) { (_, v) -> v.toMutableMap() }
+ return ServiceRegistry(res)
+ }
- /**
- * Create a copy of the registry.
- */
- public fun clone(): ServiceRegistry
+ override fun toString(): String {
+ val entries = registry.map { "${it.key}=${it.value}" }.joinToString()
+ return "ServiceRegistry{$entries}"
+ }
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistryImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistryImpl.kt
deleted file mode 100644
index bf3ee43f..00000000
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ServiceRegistryImpl.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2022 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
-
-/**
- * Implementation of the [MutableServiceRegistry] interface.
- */
-internal class ServiceRegistryImpl(private val registry: MutableMap<String, MutableMap<Class<*>, Any>> = mutableMapOf()) :
- MutableServiceRegistry {
- override fun <T : Any> resolve(
- name: String,
- type: Class<T>,
- ): T? {
- val servicesForName = registry[name] ?: return null
-
- @Suppress("UNCHECKED_CAST")
- return servicesForName[type] as T?
- }
-
- override fun <T : Any> register(
- name: String,
- type: Class<T>,
- service: T,
- ) {
- val services = registry.computeIfAbsent(name) { mutableMapOf() }
-
- if (type in services) {
- throw IllegalStateException("Duplicate service $type registered for name $name")
- }
-
- services[type] = service
- }
-
- override fun remove(
- name: String,
- type: Class<*>,
- ) {
- val services = registry[name] ?: return
- services.remove(type)
- }
-
- override fun remove(name: String) {
- registry.remove(name)
- }
-
- override fun clone(): MutableServiceRegistry {
- val res = mutableMapOf<String, MutableMap<Class<*>, Any>>()
- registry.mapValuesTo(res) { (_, v) -> v.toMutableMap() }
- return ServiceRegistryImpl(res)
- }
-
- override fun toString(): String {
- val entries = registry.map { "${it.key}=${it.value}" }.joinToString()
- return "ServiceRegistry{$entries}"
- }
-}
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
deleted file mode 100644
index e681403c..00000000
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
+++ /dev/null
@@ -1,378 +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
-
-import org.opendc.compute.api.Flavor
-import org.opendc.compute.api.Task
-import org.opendc.compute.api.TaskState
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.driver.HostListener
-import org.opendc.compute.service.driver.HostModel
-import org.opendc.compute.service.driver.HostState
-import org.opendc.compute.service.driver.telemetry.GuestCpuStats
-import org.opendc.compute.service.driver.telemetry.GuestSystemStats
-import org.opendc.compute.service.driver.telemetry.HostCpuStats
-import org.opendc.compute.service.driver.telemetry.HostSystemStats
-import org.opendc.compute.simulator.internal.DefaultWorkloadMapper
-import org.opendc.compute.simulator.internal.Guest
-import org.opendc.compute.simulator.internal.GuestListener
-import org.opendc.simulator.compute.SimBareMetalMachine
-import org.opendc.simulator.compute.SimMachineContext
-import org.opendc.simulator.compute.kernel.SimHypervisor
-import org.opendc.simulator.compute.model.MachineModel
-import org.opendc.simulator.compute.model.MemoryUnit
-import org.opendc.simulator.compute.workload.SimWorkload
-import org.opendc.simulator.compute.workload.SimWorkloads
-import java.time.Duration
-import java.time.Instant
-import java.time.InstantSource
-import java.util.UUID
-import java.util.function.Supplier
-
-/**
- * A [Host] implementation that simulates virtual machines on a physical machine using [SimHypervisor].
- *
- * @param uid The unique identifier of the host.
- * @param name The name of the host.
- * @param meta The metadata of the host.
- * @param clock The (virtual) clock used to track time.
- * @param machine The [SimBareMetalMachine] on which the host runs.
- * @param hypervisor The [SimHypervisor] to run on top of the machine.
- * @param mapper A [SimWorkloadMapper] to map a [Task] to a [SimWorkload].
- * @param bootModel A [Supplier] providing the [SimWorkload] to execute during the boot procedure of the hypervisor.
- * @param optimize A flag to indicate to optimize the machine models of the virtual machines.
- */
-public class SimHost(
- private val uid: UUID,
- private val name: String,
- private val meta: Map<String, Any>,
- private val clock: InstantSource,
- private val machine: SimBareMetalMachine,
- private val hypervisor: SimHypervisor,
- private val mapper: SimWorkloadMapper = DefaultWorkloadMapper,
- private val bootModel: Supplier<SimWorkload?> = Supplier { null },
- private val optimize: Boolean = false,
-) : Host, AutoCloseable {
- /**
- * The event listeners registered with this host.
- */
- private val listeners = mutableListOf<HostListener>()
-
- /**
- * The virtual machines running on the hypervisor.
- */
- private val guests = HashMap<Task, Guest>()
- private val localGuests = mutableListOf<Guest>()
-
- private var localState: HostState = HostState.DOWN
- set(value) {
- if (value != field) {
- listeners.forEach { it.onStateChanged(this, value) }
- }
- field = value
- }
-
- private val model: HostModel =
- HostModel(
- machine.model.cpu.totalCapacity,
- machine.model.cpu.coreCount,
- machine.model.memory.size,
- )
-
- /**
- * The [GuestListener] that listens for guest events.
- */
- private val guestListener =
- object : GuestListener {
- override fun onStart(guest: Guest) {
- listeners.forEach { it.onStateChanged(this@SimHost, guest.task, guest.state) }
- }
-
- override fun onStop(guest: Guest) {
- listeners.forEach { it.onStateChanged(this@SimHost, guest.task, guest.state) }
- }
- }
-
- init {
- launch()
- }
-
- override fun getUid(): UUID {
- return uid
- }
-
- override fun getName(): String {
- return name
- }
-
- override fun getModel(): HostModel {
- return model
- }
-
- override fun getMeta(): Map<String, *> {
- return meta
- }
-
- override fun getState(): HostState {
- return localState
- }
-
- override fun getInstances(): Set<Task> {
- return guests.keys
- }
-
- override fun canFit(task: Task): Boolean {
- val sufficientMemory = model.memoryCapacity >= task.flavor.memorySize
- val enoughCpus = model.coreCount >= task.flavor.coreCount
- val canFit = hypervisor.canFit(task.flavor.toMachineModel())
-
- return sufficientMemory && enoughCpus && canFit
- }
-
- override fun spawn(task: Task) {
- guests.computeIfAbsent(task) { key ->
- require(canFit(key)) { "Task does not fit" }
-
- val machine = hypervisor.newMachine(key.flavor.toMachineModel())
- val newGuest =
- Guest(
- clock,
- this,
- hypervisor,
- mapper,
- guestListener,
- task,
- machine,
- )
-
- localGuests.add(newGuest)
- newGuest
- }
- }
-
- override fun contains(task: Task): Boolean {
- return task in guests
- }
-
- override fun start(task: Task) {
- val guest = requireNotNull(guests[task]) { "Unknown task ${task.uid} at host $uid" }
- guest.start()
- }
-
- override fun stop(task: Task) {
- val guest = requireNotNull(guests[task]) { "Unknown task ${task.uid} at host $uid" }
- guest.stop()
- }
-
- override fun delete(task: Task) {
- val guest = guests[task] ?: return
- guest.delete()
-
- guests.remove(task)
- localGuests.remove(guest)
- }
-
- override fun addListener(listener: HostListener) {
- listeners.add(listener)
- }
-
- override fun removeListener(listener: HostListener) {
- listeners.remove(listener)
- }
-
- override fun close() {
- reset(HostState.DOWN)
- machine.cancel()
- }
-
- override fun getSystemStats(): HostSystemStats {
- updateUptime()
-
- var terminated = 0
- var running = 0
- var error = 0
- var invalid = 0
-
- val guests = localGuests.listIterator()
- for (guest in guests) {
- when (guest.state) {
- TaskState.TERMINATED -> terminated++
- TaskState.RUNNING -> running++
- TaskState.ERROR -> error++
- TaskState.DELETED -> {
- // Remove guests that have been deleted
- this.guests.remove(guest.task)
- guests.remove()
- }
- else -> invalid++
- }
- }
-
- return HostSystemStats(
- Duration.ofMillis(localUptime),
- Duration.ofMillis(localDowntime),
- localBootTime,
- machine.psu.powerDraw,
- machine.psu.energyUsage,
- terminated,
- running,
- error,
- invalid,
- )
- }
-
- override fun getSystemStats(task: Task): GuestSystemStats {
- val guest = requireNotNull(guests[task]) { "Unknown task ${task.uid} at host $uid" }
- return guest.getSystemStats()
- }
-
- override fun getCpuStats(): HostCpuStats {
- val counters = hypervisor.counters
- counters.sync()
-
- return HostCpuStats(
- counters.cpuActiveTime,
- counters.cpuIdleTime,
- counters.cpuStealTime,
- counters.cpuLostTime,
- hypervisor.cpuCapacity,
- hypervisor.cpuDemand,
- hypervisor.cpuUsage,
- hypervisor.cpuUsage / localCpuLimit,
- )
- }
-
- override fun getCpuStats(task: Task): GuestCpuStats {
- val guest = requireNotNull(guests[task]) { "Unknown task ${task.uid} at host $uid" }
- return guest.getCpuStats()
- }
-
- 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 fun fail() {
- reset(HostState.ERROR)
-
- for (guest in localGuests) {
- guest.fail()
- }
- }
-
- public fun recover() {
- updateUptime()
-
- launch()
- }
-
- /**
- * The [SimMachineContext] that represents the machine running the hypervisor.
- */
- private var ctx: SimMachineContext? = null
-
- /**
- * Launch the hypervisor.
- */
- private fun launch() {
- check(ctx == null) { "Concurrent hypervisor running" }
-
- val bootWorkload = bootModel.get()
- val hypervisor = hypervisor
- val hypervisorWorkload =
- object : SimWorkload by hypervisor {
- override fun onStart(ctx: SimMachineContext) {
- try {
- localBootTime = clock.instant()
- localState = HostState.UP
- hypervisor.onStart(ctx)
-
- // Recover the guests that were running on the hypervisor.
- for (guest in localGuests) {
- guest.recover()
- }
- } catch (cause: Throwable) {
- localState = HostState.ERROR
- throw cause
- }
- }
- }
-
- val workload = if (bootWorkload != null) SimWorkloads.chain(bootWorkload, hypervisorWorkload) else hypervisorWorkload
-
- // Launch hypervisor onto machine
- ctx =
- machine.startWorkload(workload, emptyMap()) { cause ->
- localState = if (cause != null) HostState.ERROR else HostState.DOWN
- ctx = null
- }
- }
-
- /**
- * Reset the machine.
- */
- private fun reset(state: HostState) {
- updateUptime()
-
- // Stop the hypervisor
- ctx?.shutdown()
- localState = state
- }
-
- /**
- * Convert flavor to machine model.
- */
- private fun Flavor.toMachineModel(): MachineModel {
- return MachineModel(machine.model.cpu, MemoryUnit("Generic", "Generic", 3200.0, memorySize))
- }
-
- private var localLastReport = clock.millis()
- private var localUptime = 0L
- private var localDowntime = 0L
- private var localBootTime: Instant? = null
- private val localCpuLimit = machine.model.cpu.totalCapacity
-
- /**
- * Helper function to track the uptime of a machine.
- */
- private fun updateUptime() {
- val now = clock.millis()
- val duration = now - localLastReport
- localLastReport = now
-
- if (localState == HostState.UP) {
- localUptime += duration
- } else if (localState == HostState.ERROR) {
- // Only increment downtime if the machine is in a failure state
- localDowntime += duration
- }
-
- val guests = localGuests
- for (i in guests.indices) {
- guests[i].updateUptime()
- }
- }
-}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimMetaWorkloadMapper.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimMetaWorkloadMapper.kt
deleted file mode 100644
index 907f6acd..00000000
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimMetaWorkloadMapper.kt
+++ /dev/null
@@ -1,35 +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
-
-import org.opendc.compute.api.Task
-import org.opendc.simulator.compute.workload.SimWorkload
-
-/**
- * A [SimWorkloadMapper] that maps a [Task] to a workload via the meta-data.
- */
-public class SimMetaWorkloadMapper(private val key: String = "workload") : SimWorkloadMapper {
- override fun createWorkload(task: Task): SimWorkload {
- return requireNotNull(task.meta[key] ?: task.image.meta[key]) as SimWorkload
- }
-}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimWorkloadMapper.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimWorkloadMapper.kt
deleted file mode 100644
index a85091a0..00000000
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimWorkloadMapper.kt
+++ /dev/null
@@ -1,37 +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
-
-import org.opendc.compute.api.Image
-import org.opendc.compute.api.Task
-import org.opendc.simulator.compute.workload.SimWorkload
-
-/**
- * A [SimWorkloadMapper] is responsible for mapping a [Task] and [Image] to a [SimWorkload] that can be simulated.
- */
-public fun interface SimWorkloadMapper {
- /**
- * Map the specified [task] to a [SimWorkload] that can be simulated.
- */
- public fun createWorkload(task: Task): SimWorkload
-}
diff --git a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/TaskWatcher.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/TaskWatcher.kt
index 423d7dec..9fe4dff5 100644
--- a/opendc-compute/opendc-compute-api/src/main/kotlin/org/opendc/compute/api/TaskWatcher.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/TaskWatcher.kt
@@ -20,20 +20,23 @@
* SOFTWARE.
*/
-package org.opendc.compute.api
+package org.opendc.compute.simulator
+
+import org.opendc.compute.api.TaskState
+import org.opendc.compute.simulator.service.ServiceTask
/**
- * An interface used to watch the state of [Task] instances.
+ * An interface used to watch the state of [ServiceTask] instances.
*/
public interface TaskWatcher {
/**
- * This method is invoked when the state of a [Task] changes.
+ * This method is invoked when the state of a [ServiceTask] changes.
*
* @param task The task whose state has changed.
* @param newState The new state of the task.
*/
public fun onStateChanged(
- task: Task,
+ task: ServiceTask,
newState: TaskState,
) {}
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt
new file mode 100644
index 00000000..31ff384c
--- /dev/null
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt
@@ -0,0 +1,369 @@
+/*
+ * 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.host
+
+import org.opendc.compute.api.Flavor
+import org.opendc.compute.api.TaskState
+import org.opendc.compute.simulator.internal.Guest
+import org.opendc.compute.simulator.internal.GuestListener
+import org.opendc.compute.simulator.service.ServiceTask
+import org.opendc.compute.simulator.telemetry.GuestCpuStats
+import org.opendc.compute.simulator.telemetry.GuestSystemStats
+import org.opendc.compute.simulator.telemetry.HostCpuStats
+import org.opendc.compute.simulator.telemetry.HostSystemStats
+import org.opendc.simulator.compute.cpu.CpuPowerModel
+import org.opendc.simulator.compute.machine.SimMachine
+import org.opendc.simulator.compute.models.MachineModel
+import org.opendc.simulator.compute.models.MemoryUnit
+import org.opendc.simulator.engine.FlowGraph
+import java.time.Duration
+import java.time.Instant
+import java.time.InstantSource
+import java.util.UUID
+
+/**
+ * A [Host] implementation that simulates virtual machines on a physical machine.
+ *
+ * @param uid The unique identifier of the host.
+ * @param name The name of the host.
+ * @param meta The metadata of the host.
+ * @param clock The (virtual) clock used to track time.
+ * @param graph The Flow Graph that the Host is part of
+ * @param machineModel The static model of the host
+ * @param powerModel The static powerModel of the CPU TODO: can this be combined with machinemodel?
+ * @constructor Create empty Sim host
+ */
+public class SimHost(
+ private val uid: UUID,
+ private val name: String,
+ private val meta: Map<String, Any>,
+ private val clock: InstantSource,
+ private val graph: FlowGraph,
+ private val machineModel: MachineModel,
+ private val powerModel: CpuPowerModel,
+) : AutoCloseable {
+ /**
+ * The event listeners registered with this host.
+ */
+ private val hostListeners = mutableListOf<HostListener>()
+
+ /**
+ * The virtual machines running on the hypervisor.
+ */
+ private val taskToGuestMap = HashMap<ServiceTask, Guest>()
+ private val guests = mutableListOf<Guest>()
+
+ private var hostState: HostState = HostState.DOWN
+ set(value) {
+ if (value != field) {
+ hostListeners.forEach { it.onStateChanged(this, value) }
+ }
+ field = value
+ }
+
+ private val model: HostModel =
+ HostModel(
+ machineModel.cpu.totalCapacity,
+ machineModel.cpu.coreCount,
+ machineModel.memory.size,
+ )
+
+ private var simMachine: SimMachine? = null
+
+ /**
+ * The [GuestListener] that listens for guest events.
+ */
+ private val guestListener =
+ object : GuestListener {
+ override fun onStart(guest: Guest) {
+ hostListeners.forEach { it.onStateChanged(this@SimHost, guest.task, guest.state) }
+ }
+
+ override fun onStop(guest: Guest) {
+ hostListeners.forEach { it.onStateChanged(this@SimHost, guest.task, guest.state) }
+ }
+ }
+
+ private var lastReport = clock.millis()
+ private var totalUptime = 0L
+ private var totalDowntime = 0L
+ private var bootTime: Instant? = null
+ private val cpuLimit = machineModel.cpu.totalCapacity
+
+ init {
+ launch()
+ }
+
+ /**
+ * Launch the hypervisor.
+ */
+ private fun launch() {
+ bootTime = this.clock.instant()
+ hostState = HostState.UP
+
+ if (this.simMachine != null) {
+ return
+ }
+
+ this.simMachine =
+ SimMachine(
+ this.graph,
+ this.machineModel,
+ this.powerModel,
+ ) { cause ->
+ hostState = if (cause != null) HostState.ERROR else HostState.DOWN
+ }
+ }
+
+ override fun close() {
+ reset(HostState.DOWN)
+ }
+
+ public fun fail() {
+ reset(HostState.ERROR)
+
+ // Fail the guest and delete them
+ // This weird loop is the only way I have been able to make it work.
+ while (guests.size > 0) {
+ val guest = guests[0]
+ guest.fail()
+ this.delete(guest.task)
+ }
+ }
+
+ public fun recover() {
+ updateUptime()
+
+ launch()
+ }
+
+ /**
+ * Reset the machine.
+ */
+ private fun reset(state: HostState) {
+ updateUptime()
+
+ // Stop the hypervisor
+ hostState = state
+ }
+
+ public fun getUid(): UUID {
+ return uid
+ }
+
+ public fun getName(): String {
+ return name
+ }
+
+ public fun getModel(): HostModel {
+ return model
+ }
+
+ public fun getMeta(): Map<String, *> {
+ return meta
+ }
+
+ public fun getState(): HostState {
+ return hostState
+ }
+
+ public fun getInstances(): Set<ServiceTask> {
+ return taskToGuestMap.keys
+ }
+
+ public fun getGuests(): List<Guest> {
+ return this.guests
+ }
+
+ public fun canFit(task: ServiceTask): Boolean {
+ val sufficientMemory = model.memoryCapacity >= task.flavor.memorySize
+ val enoughCpus = model.coreCount >= task.flavor.coreCount
+ val canFit = simMachine!!.canFit(task.flavor.toMachineModel())
+
+ return sufficientMemory && enoughCpus && canFit
+ }
+
+ /**
+ * Spawn A Virtual machine that run the Task and put this Task as a Guest on it
+ *
+ * @param task
+ */
+ public fun spawn(task: ServiceTask) {
+ assert(simMachine != null) { "Tried start task $task while no SimMachine is active" }
+
+ require(canFit(task)) { "Task does not fit" }
+
+ val newGuest =
+ Guest(
+ clock,
+ this,
+ guestListener,
+ task,
+ simMachine!!,
+ )
+
+ guests.add(newGuest)
+ newGuest.start()
+
+ taskToGuestMap.computeIfAbsent(task) { newGuest }
+ }
+
+ public fun contains(task: ServiceTask): Boolean {
+ return task in taskToGuestMap
+ }
+
+ public fun start(task: ServiceTask) {
+ val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.uid} at host $uid" }
+ guest.start()
+ }
+
+ public fun stop(task: ServiceTask) {
+ val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.uid} at host $uid" }
+ guest.stop()
+ }
+
+ public fun delete(task: ServiceTask) {
+ val guest = taskToGuestMap[task] ?: return
+ guest.delete()
+
+ taskToGuestMap.remove(task)
+ guests.remove(guest)
+ task.host = null
+ }
+
+ public fun removeTask(task: ServiceTask) {
+ val guest = taskToGuestMap[task] ?: return
+ guest.delete()
+
+ taskToGuestMap.remove(task)
+ guests.remove(guest)
+ }
+
+ public fun addListener(listener: HostListener) {
+ hostListeners.add(listener)
+ }
+
+ public fun removeListener(listener: HostListener) {
+ hostListeners.remove(listener)
+ }
+
+ public fun getSystemStats(): HostSystemStats {
+ updateUptime()
+ this.simMachine!!.psu.updateCounters()
+
+ var terminated = 0
+ var running = 0
+ var failed = 0
+ var invalid = 0
+ var completed = 0
+
+ val guests = guests.listIterator()
+ for (guest in guests) {
+ when (guest.state) {
+ TaskState.RUNNING -> running++
+ TaskState.COMPLETED, TaskState.FAILED, TaskState.TERMINATED -> {
+ failed++
+ // Remove guests that have been deleted
+ this.taskToGuestMap.remove(guest.task)
+ guests.remove()
+ }
+ else -> invalid++
+ }
+ }
+
+ return HostSystemStats(
+ Duration.ofMillis(totalUptime),
+ Duration.ofMillis(totalDowntime),
+ bootTime,
+ simMachine!!.psu.powerDraw,
+ simMachine!!.psu.energyUsage,
+ terminated,
+ running,
+ failed,
+ invalid,
+ )
+ }
+
+ public fun getSystemStats(task: ServiceTask): GuestSystemStats {
+ val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.uid} at host $uid" }
+ return guest.getSystemStats()
+ }
+
+ public fun getCpuStats(): HostCpuStats {
+ simMachine!!.cpu.updateCounters(this.clock.millis())
+
+ val counters = simMachine!!.performanceCounters
+
+ return HostCpuStats(
+ counters.cpuActiveTime,
+ counters.cpuIdleTime,
+ counters.cpuStealTime,
+ counters.cpuLostTime,
+ counters.cpuCapacity,
+ counters.cpuDemand,
+ counters.cpuSupply,
+ counters.cpuSupply / cpuLimit,
+ )
+ }
+
+ public fun getCpuStats(task: ServiceTask): GuestCpuStats {
+ val guest = requireNotNull(taskToGuestMap[task]) { "Unknown task ${task.uid} at host $uid" }
+ return guest.getCpuStats()
+ }
+
+ 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]"
+
+ /**
+ * Convert flavor to machine model.
+ */
+ private fun Flavor.toMachineModel(): MachineModel {
+ return MachineModel(simMachine!!.machineModel.cpu, MemoryUnit("Generic", "Generic", 3200.0, memorySize))
+ }
+
+ /**
+ * Helper function to track the uptime of a machine.
+ */
+ private fun updateUptime() {
+ val now = clock.millis()
+ val duration = now - lastReport
+ lastReport = now
+
+ if (hostState == HostState.UP) {
+ totalUptime += duration
+ } else if (hostState == HostState.ERROR) {
+ // Only increment downtime if the machine is in a failure state
+ totalDowntime += duration
+ }
+
+ val guests = guests
+ for (i in guests.indices) {
+ guests[i].updateUptime()
+ }
+ }
+}
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
deleted file mode 100644
index 412da37f..00000000
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/DefaultWorkloadMapper.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2022 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.internal
-
-import org.opendc.compute.api.Task
-import org.opendc.compute.simulator.SimMetaWorkloadMapper
-import org.opendc.compute.simulator.SimWorkloadMapper
-import org.opendc.simulator.compute.workload.SimWorkload
-import org.opendc.simulator.compute.workload.SimWorkloads
-import java.time.Duration
-
-/**
- * A [SimWorkloadMapper] to introduces a boot delay of 1 ms. This object exists to retain the old behavior while
- * introducing the possibility of adding custom boot delays.
- */
-internal object DefaultWorkloadMapper : SimWorkloadMapper {
- private val delegate = SimMetaWorkloadMapper()
-
- override fun createWorkload(task: Task): SimWorkload {
- val workload = delegate.createWorkload(task)
-
- // FIXME: look at connecting this to frontend. This does currently not work correctly
- val bootWorkload = SimWorkloads.runtime(Duration.ofMillis(0), 1.0, 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 cf6c146a..3a923222 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
@@ -23,15 +23,16 @@
package org.opendc.compute.simulator.internal
import mu.KotlinLogging
-import org.opendc.compute.api.Task
import org.opendc.compute.api.TaskState
-import org.opendc.compute.service.driver.telemetry.GuestCpuStats
-import org.opendc.compute.service.driver.telemetry.GuestSystemStats
-import org.opendc.compute.simulator.SimHost
-import org.opendc.compute.simulator.SimWorkloadMapper
-import org.opendc.simulator.compute.SimMachineContext
-import org.opendc.simulator.compute.kernel.SimHypervisor
-import org.opendc.simulator.compute.workload.SimWorkload
+import org.opendc.compute.simulator.host.SimHost
+import org.opendc.compute.simulator.service.ServiceTask
+import org.opendc.compute.simulator.telemetry.GuestCpuStats
+import org.opendc.compute.simulator.telemetry.GuestSystemStats
+import org.opendc.simulator.compute.machine.SimMachine
+import org.opendc.simulator.compute.machine.VirtualMachine
+import org.opendc.simulator.compute.workload.ChainWorkload
+import org.opendc.simulator.compute.workload.TraceFragment
+import org.opendc.simulator.compute.workload.TraceWorkload
import java.time.Duration
import java.time.Instant
import java.time.InstantSource
@@ -39,14 +40,12 @@ import java.time.InstantSource
/**
* A virtual machine instance that is managed by a [SimHost].
*/
-internal class Guest(
+public class Guest(
private val clock: InstantSource,
- val host: SimHost,
- private val hypervisor: SimHypervisor,
- private val mapper: SimWorkloadMapper,
+ public val host: SimHost,
private val listener: GuestListener,
- val task: Task,
- val machine: SimHypervisor.SimVirtualMachine,
+ public val task: ServiceTask,
+ public val simMachine: SimMachine,
) {
/**
* The state of the [Guest].
@@ -54,50 +53,133 @@ internal class Guest(
* [TaskState.PROVISIONING] is an invalid value for a guest, since it applies before the host is selected for
* a task.
*/
- var state: TaskState = TaskState.TERMINATED
+ public var state: TaskState = TaskState.CREATED
private set
/**
+ * The [VirtualMachine] on which the task is currently running
+ */
+ public var virtualMachine: VirtualMachine? = null
+
+ private var uptime = 0L
+ private var downtime = 0L
+ private var lastReport = clock.millis()
+ private var bootTime: Instant? = null
+ private val cpuLimit = simMachine.cpu.cpuModel.totalCapacity
+
+ /**
* Start the guest.
*/
- fun start() {
+ public fun start() {
when (state) {
- TaskState.TERMINATED, TaskState.ERROR -> {
+ TaskState.CREATED, TaskState.FAILED -> {
LOGGER.info { "User requested to start task ${task.uid}" }
doStart()
}
TaskState.RUNNING -> return
- TaskState.DELETED -> {
- LOGGER.warn { "User tried to start deleted task" }
- throw IllegalArgumentException("Task is deleted")
+ TaskState.COMPLETED, TaskState.TERMINATED -> {
+ LOGGER.warn { "User tried to start a finished task" }
+ throw IllegalArgumentException("Task is already finished")
}
else -> assert(false) { "Invalid state transition" }
}
}
/**
+ * Launch the guest on the simulated Virtual machine
+ */
+ private fun doStart() {
+ assert(virtualMachine == null) { "Concurrent job is already running" }
+
+ onStart()
+
+ val bootworkload =
+ TraceWorkload(
+ ArrayList(
+ listOf(
+ TraceFragment(
+ 1000000L,
+ 100000.0,
+ 1,
+ ),
+ ),
+ ),
+ 0,
+ 0,
+ 0.0,
+ )
+ val newChainWorkload =
+ ChainWorkload(
+ ArrayList(listOf(task.workload)),
+ task.workload.checkpointInterval,
+ task.workload.checkpointDuration,
+ task.workload.checkpointIntervalScaling,
+ )
+
+ virtualMachine =
+ simMachine.startWorkload(newChainWorkload) { cause ->
+ onStop(if (cause != null) TaskState.FAILED else TaskState.COMPLETED)
+ }
+ }
+
+ /**
+ * This method is invoked when the guest was started on the host and has booted into a running state.
+ */
+ private fun onStart() {
+ bootTime = clock.instant()
+ state = TaskState.RUNNING
+ listener.onStart(this)
+ }
+
+ /**
* Stop the guest.
*/
- fun stop() {
+ public fun stop() {
when (state) {
- TaskState.RUNNING -> doStop(TaskState.TERMINATED)
- TaskState.ERROR -> doRecover()
- TaskState.TERMINATED, TaskState.DELETED -> return
+ TaskState.RUNNING -> doStop(TaskState.COMPLETED)
+ TaskState.FAILED -> state = TaskState.TERMINATED
+ TaskState.COMPLETED, TaskState.TERMINATED -> return
else -> assert(false) { "Invalid state transition" }
}
}
/**
+ * Attempt to stop the task and put it into [target] state.
+ */
+ private fun doStop(target: TaskState) {
+ assert(virtualMachine != null) { "Invalid job state" }
+ val virtualMachine = this.virtualMachine ?: return
+ if (target == TaskState.FAILED) {
+ virtualMachine.shutdown(Exception("Task has failed"))
+ } else {
+ virtualMachine.shutdown()
+ }
+
+ this.virtualMachine = null
+
+ this.state = target
+ }
+
+ /**
+ * This method is invoked when the guest stopped.
+ */
+ private fun onStop(target: TaskState) {
+ updateUptime()
+
+ state = target
+ listener.onStop(this)
+ }
+
+ /**
* Delete the guest.
*
* This operation will stop the guest if it is running on the host and remove all resources associated with the
* guest.
*/
- fun delete() {
+ public fun delete() {
stop()
- state = TaskState.DELETED
- hypervisor.removeMachine(machine)
+ state = TaskState.FAILED
}
/**
@@ -105,19 +187,19 @@ internal class Guest(
*
* This operation forcibly stops the guest and puts the task into an error state.
*/
- fun fail() {
+ public fun fail() {
if (state != TaskState.RUNNING) {
return
}
- doStop(TaskState.ERROR)
+ doStop(TaskState.FAILED)
}
/**
* Recover the guest if it is in an error state.
*/
- fun recover() {
- if (state != TaskState.ERROR) {
+ public fun recover() {
+ if (state != TaskState.FAILED) {
return
}
@@ -127,117 +209,46 @@ internal class Guest(
/**
* Obtain the system statistics of this guest.
*/
- fun getSystemStats(): GuestSystemStats {
+ public fun getSystemStats(): GuestSystemStats {
updateUptime()
return GuestSystemStats(
- Duration.ofMillis(localUptime),
- Duration.ofMillis(localDowntime),
- localBootTime,
+ Duration.ofMillis(uptime),
+ Duration.ofMillis(downtime),
+ bootTime,
)
}
/**
* Obtain the CPU statistics of this guest.
*/
- fun getCpuStats(): GuestCpuStats {
- val counters = machine.counters
- counters.sync()
+ public fun getCpuStats(): GuestCpuStats {
+ virtualMachine!!.updateCounters(this.clock.millis())
+ val counters = virtualMachine!!.performanceCounters
return GuestCpuStats(
counters.cpuActiveTime / 1000L,
counters.cpuIdleTime / 1000L,
counters.cpuStealTime / 1000L,
counters.cpuLostTime / 1000L,
- machine.cpuCapacity,
- machine.cpuUsage,
- machine.cpuUsage / localCpuLimit,
+ counters.cpuCapacity,
+ counters.cpuSupply,
+ counters.cpuSupply / cpuLimit,
)
}
/**
- * The [SimMachineContext] representing the current active virtual machine instance or `null` if no virtual machine
- * is active.
- */
- private var ctx: SimMachineContext? = null
-
- /**
- * Launch the guest on the simulated
- */
- private fun doStart() {
- assert(ctx == null) { "Concurrent job running" }
-
- onStart()
-
- val workload: SimWorkload = mapper.createWorkload(task)
- workload.setOffset(clock.millis())
- val meta = mapOf("driver" to host, "task" to task) + task.meta
- ctx =
- machine.startWorkload(workload, meta) { cause ->
- onStop(if (cause != null) TaskState.ERROR else TaskState.TERMINATED)
- ctx = null
- }
- }
-
- /**
- * Attempt to stop the task and put it into [target] state.
- */
- private fun doStop(target: TaskState) {
- assert(ctx != null) { "Invalid job state" }
- val ctx = ctx ?: return
- if (target == TaskState.ERROR) {
- ctx.shutdown(Exception("Stopped because of ERROR"))
- } else {
- ctx.shutdown()
- }
-
- state = target
- }
-
- /**
- * Attempt to recover from an error state.
- */
- private fun doRecover() {
- state = TaskState.TERMINATED
- }
-
- /**
- * This method is invoked when the guest was started on the host and has booted into a running state.
- */
- private fun onStart() {
- localBootTime = clock.instant()
- state = TaskState.RUNNING
- listener.onStart(this)
- }
-
- /**
- * This method is invoked when the guest stopped.
- */
- private fun onStop(target: TaskState) {
- updateUptime()
-
- state = target
- listener.onStop(this)
- }
-
- private var localUptime = 0L
- private var localDowntime = 0L
- private var localLastReport = clock.millis()
- private var localBootTime: Instant? = null
- private val localCpuLimit = machine.model.cpu.totalCapacity
-
- /**
* Helper function to track the uptime and downtime of the guest.
*/
- fun updateUptime() {
+ public fun updateUptime() {
val now = clock.millis()
- val duration = now - localLastReport
- localLastReport = now
+ val duration = now - lastReport
+ lastReport = now
if (state == TaskState.RUNNING) {
- localUptime += duration
- } else if (state == TaskState.ERROR) {
- localDowntime += duration
+ uptime += duration
+ } else if (state == TaskState.FAILED) {
+ downtime += duration
}
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/GuestListener.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/GuestListener.kt
index e6d0fdad..895d78f9 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/GuestListener.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/GuestListener.kt
@@ -25,14 +25,14 @@ package org.opendc.compute.simulator.internal
/**
* Helper interface to listen for [Guest] events.
*/
-internal interface GuestListener {
+public interface GuestListener {
/**
* This method is invoked when the guest machine is running.
*/
- fun onStart(guest: Guest)
+ public fun onStart(guest: Guest)
/**
* This method is invoked when the guest machine is stopped.
*/
- fun onStop(guest: Guest)
+ public fun onStop(guest: Guest)
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeMonitorProvisioningStep.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeMonitorProvisioningStep.kt
index f1123742..f295f522 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeMonitorProvisioningStep.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeMonitorProvisioningStep.kt
@@ -23,9 +23,9 @@
package org.opendc.compute.simulator.provisioner
import org.opendc.compute.carbon.CarbonTrace
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.telemetry.ComputeMetricReader
-import org.opendc.compute.telemetry.ComputeMonitor
+import org.opendc.compute.simulator.service.ComputeService
+import org.opendc.compute.simulator.telemetry.ComputeMetricReader
+import org.opendc.compute.simulator.telemetry.ComputeMonitor
import java.time.Duration
/**
@@ -44,7 +44,15 @@ public class ComputeMonitorProvisioningStep(
requireNotNull(
ctx.registry.resolve(serviceDomain, ComputeService::class.java),
) { "Compute service $serviceDomain does not exist" }
- val metricReader = ComputeMetricReader(ctx.dispatcher, service, monitor, exportInterval, startTime, carbonTrace)
+ val metricReader =
+ ComputeMetricReader(
+ ctx.dispatcher,
+ service,
+ monitor,
+ exportInterval,
+ startTime,
+ carbonTrace,
+ )
return AutoCloseable { metricReader.close() }
}
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeServiceProvisioningStep.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeServiceProvisioningStep.kt
index 645c9d46..6bdb131f 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeServiceProvisioningStep.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeServiceProvisioningStep.kt
@@ -22,8 +22,8 @@
package org.opendc.compute.simulator.provisioner
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.scheduler.ComputeScheduler
+import org.opendc.compute.simulator.scheduler.ComputeScheduler
+import org.opendc.compute.simulator.service.ComputeService
import java.time.Duration
/**
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeSteps.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeSteps.kt
index afde8219..07db3d26 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeSteps.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ComputeSteps.kt
@@ -25,9 +25,8 @@
package org.opendc.compute.simulator.provisioner
import org.opendc.compute.carbon.CarbonTrace
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.scheduler.ComputeScheduler
-import org.opendc.compute.telemetry.ComputeMonitor
+import org.opendc.compute.simulator.scheduler.ComputeScheduler
+import org.opendc.compute.simulator.telemetry.ComputeMonitor
import org.opendc.compute.topology.specs.HostSpec
import java.time.Duration
@@ -41,7 +40,7 @@ import java.time.Duration
public fun setupComputeService(
serviceDomain: String,
scheduler: (ProvisioningContext) -> ComputeScheduler,
- schedulingQuantum: Duration = Duration.ofMinutes(5),
+ schedulingQuantum: Duration = Duration.ofSeconds(1),
maxNumFailures: Int = 10,
): ProvisioningStep {
return ComputeServiceProvisioningStep(serviceDomain, scheduler, schedulingQuantum, maxNumFailures)
@@ -76,7 +75,6 @@ public fun registerComputeMonitor(
public fun setupHosts(
serviceDomain: String,
specs: List<HostSpec>,
- optimize: Boolean = false,
): ProvisioningStep {
- return HostsProvisioningStep(serviceDomain, specs, optimize)
+ return HostsProvisioningStep(serviceDomain, specs)
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt
index a80be634..19674d5e 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt
@@ -22,13 +22,10 @@
package org.opendc.compute.simulator.provisioner
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.simulator.SimHost
+import org.opendc.compute.simulator.host.SimHost
+import org.opendc.compute.simulator.service.ComputeService
import org.opendc.compute.topology.specs.HostSpec
-import org.opendc.simulator.compute.SimBareMetalMachine
-import org.opendc.simulator.compute.kernel.SimHypervisor
-import org.opendc.simulator.flow2.FlowEngine
-import java.util.SplittableRandom
+import org.opendc.simulator.engine.FlowEngine
/**
* A [ProvisioningStep] that provisions a list of hosts for a [ComputeService].
@@ -40,30 +37,27 @@ import java.util.SplittableRandom
public class HostsProvisioningStep internal constructor(
private val serviceDomain: String,
private val specs: List<HostSpec>,
- private val optimize: Boolean,
) : ProvisioningStep {
override fun apply(ctx: ProvisioningContext): AutoCloseable {
val service =
requireNotNull(
ctx.registry.resolve(serviceDomain, ComputeService::class.java),
) { "Compute service $serviceDomain does not exist" }
- val engine = FlowEngine.create(ctx.dispatcher)
- val graph = engine.newGraph()
val hosts = mutableSetOf<SimHost>()
- for (spec in specs) {
- val machine = SimBareMetalMachine.create(graph, spec.model, spec.psuFactory)
- val hypervisor = SimHypervisor.create(spec.multiplexerFactory, SplittableRandom(ctx.seeder.nextLong()))
+ val flowEngine = FlowEngine.create(ctx.dispatcher)
+ val flowGraph = flowEngine.newGraph()
+ for (spec in specs) {
val host =
SimHost(
spec.uid,
spec.name,
spec.meta,
ctx.dispatcher.timeSource,
- machine,
- hypervisor,
- optimize = optimize,
+ flowGraph,
+ spec.model,
+ spec.cpuPowerModel,
)
require(hosts.add(host)) { "Host with uid ${spec.uid} already exists" }
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/Provisioner.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/Provisioner.kt
index 58d3a8c2..2e76478e 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/Provisioner.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/Provisioner.kt
@@ -23,9 +23,7 @@
package org.opendc.compute.simulator.provisioner
import org.opendc.common.Dispatcher
-import org.opendc.compute.simulator.MutableServiceRegistry
import org.opendc.compute.simulator.ServiceRegistry
-import org.opendc.compute.simulator.ServiceRegistryImpl
import java.util.ArrayDeque
import java.util.SplittableRandom
@@ -47,7 +45,7 @@ public class Provisioner(dispatcher: Dispatcher, seed: Long) : AutoCloseable {
object : ProvisioningContext {
override val dispatcher: Dispatcher = dispatcher
override val seeder: SplittableRandom = SplittableRandom(seed)
- override val registry: MutableServiceRegistry = ServiceRegistryImpl()
+ override val registry: ServiceRegistry = ServiceRegistry()
override fun toString(): String = "Provisioner.ProvisioningContext"
}
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ProvisioningContext.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ProvisioningContext.kt
index 1788c8e2..20c441c4 100644
--- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ProvisioningContext.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/ProvisioningContext.kt
@@ -23,7 +23,7 @@
package org.opendc.compute.simulator.provisioner
import org.opendc.common.Dispatcher
-import org.opendc.compute.simulator.MutableServiceRegistry
+import org.opendc.compute.simulator.ServiceRegistry
import java.util.SplittableRandom
import java.util.random.RandomGenerator
@@ -44,7 +44,7 @@ public interface ProvisioningContext {
public val seeder: RandomGenerator
/**
- * A [MutableServiceRegistry] where the provisioned services are registered.
+ * A [ServiceRegistry] where the provisioned services are registered.
*/
- public val registry: MutableServiceRegistry
+ public val registry: ServiceRegistry
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeScheduler.kt
index 42de9ebc..f0a2c3b4 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeScheduler.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeScheduler.kt
@@ -20,14 +20,13 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler
+package org.opendc.compute.simulator.scheduler
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
- * A generic scheduler interface used by the [ComputeService] to select hosts to place [Task]s on.
+ * A generic scheduler interface used by the [ComputeService] to select hosts to place [ServiceTask]s on.
*/
public interface ComputeScheduler {
/**
@@ -46,5 +45,5 @@ public interface ComputeScheduler {
* @param task The server to select a host for.
* @return The host to schedule the server on or `null` if no server is available.
*/
- public fun select(task: Task): HostView?
+ public fun select(task: ServiceTask): HostView?
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt
index 7fcc670f..ec3aedcb 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ComputeSchedulers.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt
@@ -22,15 +22,15 @@
@file:JvmName("ComputeSchedulers")
-package org.opendc.compute.service.scheduler
+package org.opendc.compute.simulator.scheduler
-import org.opendc.compute.service.scheduler.filters.ComputeFilter
-import org.opendc.compute.service.scheduler.filters.RamFilter
-import org.opendc.compute.service.scheduler.filters.VCpuFilter
-import org.opendc.compute.service.scheduler.weights.CoreRamWeigher
-import org.opendc.compute.service.scheduler.weights.InstanceCountWeigher
-import org.opendc.compute.service.scheduler.weights.RamWeigher
-import org.opendc.compute.service.scheduler.weights.VCpuWeigher
+import org.opendc.compute.simulator.scheduler.filters.ComputeFilter
+import org.opendc.compute.simulator.scheduler.filters.RamFilter
+import org.opendc.compute.simulator.scheduler.filters.VCpuFilter
+import org.opendc.compute.simulator.scheduler.weights.CoreRamWeigher
+import org.opendc.compute.simulator.scheduler.weights.InstanceCountWeigher
+import org.opendc.compute.simulator.scheduler.weights.RamWeigher
+import org.opendc.compute.simulator.scheduler.weights.VCpuWeigher
import java.util.SplittableRandom
import java.util.random.RandomGenerator
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/FilterScheduler.kt
index 772a470d..9fd3a862 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/FilterScheduler.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/FilterScheduler.kt
@@ -20,19 +20,19 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler
+package org.opendc.compute.simulator.scheduler
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
-import org.opendc.compute.service.scheduler.filters.HostFilter
-import org.opendc.compute.service.scheduler.weights.HostWeigher
+import org.opendc.compute.simulator.scheduler.filters.HostFilter
+import org.opendc.compute.simulator.scheduler.weights.HostWeigher
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
import java.util.SplittableRandom
import java.util.random.RandomGenerator
import kotlin.math.min
/**
* A [ComputeScheduler] implementation that uses filtering and weighing passes to select
- * the host to schedule a [Task] on.
+ * the host to schedule a [ServiceTask] on.
*
* This implementation is based on the filter scheduler from OpenStack Nova.
* See: https://docs.openstack.org/nova/latest/user/filter-scheduler.html
@@ -65,7 +65,7 @@ public class FilterScheduler(
hosts.remove(host)
}
- override fun select(task: Task): HostView? {
+ override fun select(task: ServiceTask): HostView? {
val hosts = hosts
val filteredHosts = hosts.filter { host -> filters.all { filter -> filter.test(host, task) } }
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ReplayScheduler.kt
index d1690ddf..43e366d9 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/ReplayScheduler.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ReplayScheduler.kt
@@ -20,11 +20,11 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler
+package org.opendc.compute.simulator.scheduler
import mu.KotlinLogging
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
* Policy replaying VM-cluster assignment.
@@ -48,11 +48,11 @@ public class ReplayScheduler(private val vmPlacements: Map<String, String>) : Co
hosts.remove(host)
}
- override fun select(task: Task): HostView? {
+ override fun select(task: ServiceTask): HostView? {
val clusterName =
vmPlacements[task.name]
?: throw IllegalStateException("Could not find placement data in VM placement file for VM ${task.name}")
- val machinesInCluster = hosts.filter { it.host.name.contains(clusterName) }
+ val machinesInCluster = hosts.filter { it.host.getName().contains(clusterName) }
if (machinesInCluster.isEmpty()) {
logger.info { "Could not find any machines belonging to cluster $clusterName for image ${task.name}, assigning randomly." }
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/ComputeFilter.kt
index 2ad626f3..99a9390e 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/ComputeFilter.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/ComputeFilter.kt
@@ -20,11 +20,11 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.filters
+package org.opendc.compute.simulator.scheduler.filters
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
-import org.opendc.compute.service.driver.HostState
+import org.opendc.compute.simulator.host.HostState
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
* A [HostFilter] that filters on active hosts.
@@ -32,9 +32,9 @@ import org.opendc.compute.service.driver.HostState
public class ComputeFilter : HostFilter {
override fun test(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Boolean {
- val result = host.host.state == HostState.UP
+ val result = host.host.getState() == HostState.UP
return result
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/DifferentHostFilter.kt
index ffafeaa9..279a2717 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/DifferentHostFilter.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/DifferentHostFilter.kt
@@ -20,10 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.filters
+package org.opendc.compute.simulator.scheduler.filters
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
import java.util.UUID
/**
@@ -32,10 +32,10 @@ import java.util.UUID
public class DifferentHostFilter : HostFilter {
override fun test(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Boolean {
@Suppress("UNCHECKED_CAST")
val affinityUUIDs = task.meta["scheduler_hint:different_host"] as? Set<UUID> ?: return true
- return host.host.instances.none { it.uid in affinityUUIDs }
+ return host.host.getInstances().none { it.uid in affinityUUIDs }
}
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/HostFilter.kt
index f506127a..bb9c1cbf 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/HostFilter.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/HostFilter.kt
@@ -20,11 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.filters
+package org.opendc.compute.simulator.scheduler.filters
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
-import org.opendc.compute.service.scheduler.FilterScheduler
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
* A filter used by the [FilterScheduler] to filter hosts.
@@ -36,6 +35,6 @@ public fun interface HostFilter {
*/
public fun test(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Boolean
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/InstanceCountFilter.kt
index 7d5eb400..53d68acf 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/InstanceCountFilter.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/InstanceCountFilter.kt
@@ -20,10 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.filters
+package org.opendc.compute.simulator.scheduler.filters
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
* A [HostFilter] that filters hosts based on the number of instances on the host.
@@ -33,7 +33,7 @@ import org.opendc.compute.service.HostView
public class InstanceCountFilter(private val limit: Int) : HostFilter {
override fun test(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Boolean {
return host.instanceCount < limit
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/RamFilter.kt
index 0a28ccc6..0b570d52 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/RamFilter.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/RamFilter.kt
@@ -20,24 +20,24 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.filters
+package org.opendc.compute.simulator.scheduler.filters
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
- * A [HostFilter] that filters hosts based on the memory requirements of a [Task] and the RAM available on the host.
+ * A [HostFilter] that filters hosts based on the memory requirements of a [ServiceTask] and the RAM available on the host.
*
* @param allocationRatio Virtual RAM to physical RAM allocation ratio.
*/
public class RamFilter(private val allocationRatio: Double) : HostFilter {
override fun test(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Boolean {
val requestedMemory = task.flavor.memorySize
val availableMemory = host.availableMemory
- val memoryCapacity = host.host.model.memoryCapacity
+ val memoryCapacity = host.host.getModel().memoryCapacity
// Do not allow an instance to overcommit against itself, only against
// other instances.
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/SameHostFilter.kt
index d8634285..761b125d 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/SameHostFilter.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/SameHostFilter.kt
@@ -20,10 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.filters
+package org.opendc.compute.simulator.scheduler.filters
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
import java.util.UUID
/**
@@ -32,10 +32,10 @@ import java.util.UUID
public class SameHostFilter : HostFilter {
override fun test(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Boolean {
@Suppress("UNCHECKED_CAST")
val affinityUUIDs = task.meta["scheduler_hint:same_host"] as? Set<UUID> ?: return true
- return host.host.instances.any { it.uid in affinityUUIDs }
+ return host.host.getInstances().any { it.uid in affinityUUIDs }
}
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuCapacityFilter.kt
index 5af7ccf0..256caa94 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuCapacityFilter.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuCapacityFilter.kt
@@ -20,23 +20,22 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.filters
+package org.opendc.compute.simulator.scheduler.filters
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
- * A [HostFilter] that filters hosts based on the vCPU speed requirements of a [Task] and the available
+ * A [HostFilter] that filters hosts based on the vCPU speed requirements of a [ServiceTask] and the available
* capacity on the host.
*/
public class VCpuCapacityFilter : HostFilter {
override fun test(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Boolean {
val requiredCapacity = task.flavor.meta["cpu-capacity"] as? Double
- val hostModel = host.host.model
- val availableCapacity = hostModel.cpuCapacity
+ val availableCapacity = host.host.getModel().cpuCapacity
return requiredCapacity == null || availableCapacity >= (requiredCapacity / task.flavor.coreCount)
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuFilter.kt
index 442e58f6..c179a7bf 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/filters/VCpuFilter.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuFilter.kt
@@ -20,23 +20,23 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.filters
+package org.opendc.compute.simulator.scheduler.filters
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
- * A [HostFilter] that filters hosts based on the vCPU requirements of a [Task] and the available vCPUs on the host.
+ * A [HostFilter] that filters hosts based on the vCPU requirements of a [ServiceTask] and the available vCPUs on the host.
*
* @param allocationRatio Virtual CPU to physical CPU allocation ratio.
*/
public class VCpuFilter(private val allocationRatio: Double) : HostFilter {
override fun test(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Boolean {
val requested = task.flavor.coreCount
- val totalCores = host.host.model.coreCount
+ val totalCores = host.host.getModel().coreCount
val limit = totalCores * allocationRatio
// Do not allow an instance to overcommit against itself, only against other instances
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/CoreRamWeigher.kt
index 6e320bf4..b6c43c10 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/CoreRamWeigher.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/CoreRamWeigher.kt
@@ -20,10 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.weights
+package org.opendc.compute.simulator.scheduler.weights
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
* A [HostWeigher] that weighs the hosts based on the available memory per core on the host.
@@ -35,7 +35,7 @@ import org.opendc.compute.service.HostView
public class CoreRamWeigher(override val multiplier: Double = 1.0) : HostWeigher {
override fun getWeight(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Double {
return host.availableMemory.toDouble()
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/HostWeigher.kt
index 3f2c4123..c1e0c590 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/HostWeigher.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/HostWeigher.kt
@@ -20,11 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.weights
+package org.opendc.compute.simulator.scheduler.weights
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
-import org.opendc.compute.service.scheduler.FilterScheduler
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
* An interface used by the [FilterScheduler] to weigh the pool of host for a scheduling request.
@@ -36,11 +35,11 @@ public interface HostWeigher {
public val multiplier: Double
/**
- * Obtain the weight of the specified [host] when scheduling the specified [task].
+ * Obtain the weight of the specified [host] when scheduling the specified [ServiceTask].
*/
public fun getWeight(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Double
/**
@@ -48,7 +47,7 @@ public interface HostWeigher {
*/
public fun getWeights(
hosts: List<HostView>,
- task: Task,
+ task: ServiceTask,
): Result {
val weights = DoubleArray(hosts.size)
var min = Double.MAX_VALUE
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/InstanceCountWeigher.kt
index 0789f109..9277c1ae 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/InstanceCountWeigher.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/InstanceCountWeigher.kt
@@ -20,10 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.weights
+package org.opendc.compute.simulator.scheduler.weights
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
* A [HostWeigher] that weighs the hosts based on the number of instances on the host.
@@ -31,7 +31,7 @@ import org.opendc.compute.service.HostView
public class InstanceCountWeigher(override val multiplier: Double = 1.0) : HostWeigher {
override fun getWeight(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Double {
return host.instanceCount.toDouble()
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/RamWeigher.kt
index fb03d064..1cbfea59 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/RamWeigher.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/RamWeigher.kt
@@ -20,10 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.weights
+package org.opendc.compute.simulator.scheduler.weights
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
* A [HostWeigher] that weighs the hosts based on the available RAM (memory) on the host.
@@ -34,7 +34,7 @@ import org.opendc.compute.service.HostView
public class RamWeigher(override val multiplier: Double = 1.0) : HostWeigher {
override fun getWeight(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Double {
return host.availableMemory.toDouble()
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VCpuCapacityWeigher.kt
index 5f99cab3..4f52e11a 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuCapacityWeigher.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VCpuCapacityWeigher.kt
@@ -20,10 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.weights
+package org.opendc.compute.simulator.scheduler.weights
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
* A [HostWeigher] that weighs the hosts based on the difference required vCPU capacity and the available CPU capacity.
@@ -31,9 +31,9 @@ import org.opendc.compute.service.HostView
public class VCpuCapacityWeigher(override val multiplier: Double = 1.0) : HostWeigher {
override fun getWeight(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Double {
- val model = host.host.model
+ val model = host.host.getModel()
val requiredCapacity = task.flavor.meta["cpu-capacity"] as? Double ?: 0.0
return model.cpuCapacity - requiredCapacity / task.flavor.coreCount
}
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VCpuWeigher.kt
index 0c3d9c21..3f9a7f03 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/scheduler/weights/VCpuWeigher.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VCpuWeigher.kt
@@ -20,10 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.service.scheduler.weights
+package org.opendc.compute.simulator.scheduler.weights
-import org.opendc.compute.api.Task
-import org.opendc.compute.service.HostView
+import org.opendc.compute.simulator.service.HostView
+import org.opendc.compute.simulator.service.ServiceTask
/**
* A [HostWeigher] that weighs the hosts based on the remaining number of vCPUs available.
@@ -37,7 +37,7 @@ public class VCpuWeigher(private val allocationRatio: Double, override val multi
override fun getWeight(
host: HostView,
- task: Task,
+ task: ServiceTask,
): Double {
return allocationRatio - host.provisionedCores
}
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/ComputeMetricReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt
index 56cda31c..d5fb991d 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/ComputeMetricReader.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMetricReader.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry
+package org.opendc.compute.simulator.telemetry
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
@@ -29,16 +29,16 @@ import kotlinx.coroutines.launch
import mu.KotlinLogging
import org.opendc.common.Dispatcher
import org.opendc.common.asCoroutineDispatcher
-import org.opendc.compute.api.Task
import org.opendc.compute.api.TaskState
import org.opendc.compute.carbon.CarbonTrace
-import org.opendc.compute.service.ComputeService
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.telemetry.table.HostInfo
-import org.opendc.compute.telemetry.table.HostTableReader
-import org.opendc.compute.telemetry.table.ServiceTableReader
-import org.opendc.compute.telemetry.table.TaskInfo
-import org.opendc.compute.telemetry.table.TaskTableReader
+import org.opendc.compute.simulator.host.SimHost
+import org.opendc.compute.simulator.service.ComputeService
+import org.opendc.compute.simulator.service.ServiceTask
+import org.opendc.compute.simulator.telemetry.table.HostInfo
+import org.opendc.compute.simulator.telemetry.table.HostTableReader
+import org.opendc.compute.simulator.telemetry.table.ServiceTableReader
+import org.opendc.compute.simulator.telemetry.table.TaskInfo
+import org.opendc.compute.simulator.telemetry.table.TaskTableReader
import java.time.Duration
import java.time.Instant
@@ -66,17 +66,23 @@ public class ComputeMetricReader(
/**
* Aggregator for service metrics.
*/
- private val serviceTableReader = ServiceTableReaderImpl(service, startTime)
+ private val serviceTableReader =
+ ServiceTableReaderImpl(
+ service,
+ startTime,
+ )
+
+ private var loggCounter = 0
/**
* Mapping from [Host] instances to [HostTableReaderImpl]
*/
- private val hostTableReaders = mutableMapOf<Host, HostTableReaderImpl>()
+ private val hostTableReaders = mutableMapOf<SimHost, HostTableReaderImpl>()
/**
* Mapping from [Task] instances to [TaskTableReaderImpl]
*/
- private val taskTableReaders = mutableMapOf<Task, TaskTableReaderImpl>()
+ private val taskTableReaders = mutableMapOf<ServiceTask, TaskTableReaderImpl>()
/**
* The background job that is responsible for collecting the metrics every cycle.
@@ -100,25 +106,57 @@ public class ComputeMetricReader(
}
private fun loggState() {
+ loggCounter++
try {
val now = this.clock.instant()
for (host in this.service.hosts) {
- val reader = this.hostTableReaders.computeIfAbsent(host) { HostTableReaderImpl(it, startTime, carbonTrace) }
+ val reader =
+ this.hostTableReaders.computeIfAbsent(host) {
+ HostTableReaderImpl(
+ it,
+ startTime,
+ carbonTrace,
+ )
+ }
reader.record(now)
this.monitor.record(reader.copy())
reader.reset()
}
for (task in this.service.tasks) {
- val reader = this.taskTableReaders.computeIfAbsent(task) { TaskTableReaderImpl(service, it, startTime) }
+ val reader =
+ this.taskTableReaders.computeIfAbsent(task) {
+ TaskTableReaderImpl(
+ service,
+ it,
+ startTime,
+ )
+ }
reader.record(now)
this.monitor.record(reader.copy())
reader.reset()
}
+ for (task in this.service.tasksToRemove) {
+ task.delete()
+ }
+ this.service.clearTasksToRemove()
+
this.serviceTableReader.record(now)
monitor.record(this.serviceTableReader.copy())
+
+ if (loggCounter >= 100) {
+ var loggString = "\n\t\t\t\t\tMetrics after ${now.toEpochMilli() / 1000 / 60 / 60} hours:\n"
+ loggString += "\t\t\t\t\t\tTasks Total: ${this.serviceTableReader.tasksTotal}\n"
+ loggString += "\t\t\t\t\t\tTasks Active: ${this.serviceTableReader.tasksActive}\n"
+ loggString += "\t\t\t\t\t\tTasks Pending: ${this.serviceTableReader.tasksPending}\n"
+ loggString += "\t\t\t\t\t\tTasks Completed: ${this.serviceTableReader.tasksCompleted}\n"
+ loggString += "\t\t\t\t\t\tTasks Terminated: ${this.serviceTableReader.tasksTerminated}\n"
+
+ this.logger.warn { loggString }
+ loggCounter = 0
+ }
} catch (cause: Throwable) {
this.logger.warn(cause) { "Exporter threw an Exception" }
}
@@ -136,7 +174,10 @@ public class ComputeMetricReader(
private val startTime: Duration = Duration.ofMillis(0),
) : ServiceTableReader {
override fun copy(): ServiceTableReader {
- val newServiceTable = ServiceTableReaderImpl(service)
+ val newServiceTable =
+ ServiceTableReaderImpl(
+ service,
+ )
newServiceTable.setValues(this)
return newServiceTable
@@ -151,9 +192,10 @@ public class ComputeMetricReader(
_tasksTotal = table.tasksTotal
_tasksPending = table.tasksPending
_tasksActive = table.tasksActive
+ _tasksCompleted = table.tasksCompleted
+ _tasksTerminated = table.tasksTerminated
_attemptsSuccess = table.attemptsSuccess
_attemptsFailure = table.attemptsFailure
- _attemptsError = table.attemptsError
}
private var _timestamp: Instant = Instant.MIN
@@ -180,10 +222,18 @@ public class ComputeMetricReader(
get() = _tasksPending
private var _tasksPending = 0
+ override val tasksCompleted: Int
+ get() = _tasksCompleted
+ private var _tasksCompleted = 0
+
override val tasksActive: Int
get() = _tasksActive
private var _tasksActive = 0
+ override val tasksTerminated: Int
+ get() = _tasksTerminated
+ private var _tasksTerminated = 0
+
override val attemptsSuccess: Int
get() = _attemptsSuccess
private var _attemptsSuccess = 0
@@ -192,10 +242,6 @@ public class ComputeMetricReader(
get() = _attemptsFailure
private var _attemptsFailure = 0
- override val attemptsError: Int
- get() = _attemptsError
- private var _attemptsError = 0
-
/**
* Record the next cycle.
*/
@@ -208,10 +254,11 @@ public class ComputeMetricReader(
_hostsDown = stats.hostsUnavailable
_tasksTotal = stats.tasksTotal
_tasksPending = stats.tasksPending
+ _tasksCompleted = stats.tasksCompleted
_tasksActive = stats.tasksActive
+ _tasksTerminated = stats.tasksTerminated
_attemptsSuccess = stats.attemptsSuccess.toInt()
_attemptsFailure = stats.attemptsFailure.toInt()
- _attemptsError = stats.attemptsError.toInt()
}
}
@@ -219,12 +266,13 @@ public class ComputeMetricReader(
* An aggregator for host metrics before they are reported.
*/
private class HostTableReaderImpl(
- host: Host,
+ host: SimHost,
private val startTime: Duration = Duration.ofMillis(0),
private val carbonTrace: CarbonTrace = CarbonTrace(null),
) : HostTableReader {
override fun copy(): HostTableReader {
- val newHostTable = HostTableReaderImpl(_host)
+ val newHostTable =
+ HostTableReaderImpl(_host)
newHostTable.setValues(this)
return newHostTable
@@ -259,7 +307,14 @@ public class ComputeMetricReader(
private val _host = host
override val host: HostInfo =
- HostInfo(host.uid.toString(), host.name, "x86", host.model.coreCount, host.model.cpuCapacity, host.model.memoryCapacity)
+ HostInfo(
+ host.getUid().toString(),
+ host.getName(),
+ "x86",
+ host.getModel().coreCount,
+ host.getModel().cpuCapacity,
+ host.getModel().memoryCapacity,
+ )
override val timestamp: Instant
get() = _timestamp
@@ -285,21 +340,21 @@ public class ComputeMetricReader(
get() = _guestsInvalid
private var _guestsInvalid = 0
- override val cpuLimit: Double
+ override val cpuLimit: Float
get() = _cpuLimit
- private var _cpuLimit = 0.0
+ private var _cpuLimit = 0.0f
- override val cpuUsage: Double
+ override val cpuUsage: Float
get() = _cpuUsage
- private var _cpuUsage = 0.0
+ private var _cpuUsage = 0.0f
- override val cpuDemand: Double
+ override val cpuDemand: Float
get() = _cpuDemand
- private var _cpuDemand = 0.0
+ private var _cpuDemand = 0.0f
- override val cpuUtilization: Double
+ override val cpuUtilization: Float
get() = _cpuUtilization
- private var _cpuUtilization = 0.0
+ private var _cpuUtilization = 0.0f
override val cpuActiveTime: Long
get() = _cpuActiveTime - previousCpuActiveTime
@@ -321,22 +376,22 @@ public class ComputeMetricReader(
private var _cpuLostTime = 0L
private var previousCpuLostTime = 0L
- override val powerDraw: Double
+ override val powerDraw: Float
get() = _powerDraw
- private var _powerDraw = 0.0
+ private var _powerDraw = 0.0f
- override val energyUsage: Double
- get() = _energyUsage - previousPowerTotal
- private var _energyUsage = 0.0
- private var previousPowerTotal = 0.0
+ override val energyUsage: Float
+ get() = _energyUsage - previousEnergyUsage
+ private var _energyUsage = 0.0f
+ private var previousEnergyUsage = 0.0f
- override val carbonIntensity: Double
+ override val carbonIntensity: Float
get() = _carbonIntensity
- private var _carbonIntensity = 0.0
+ private var _carbonIntensity = 0.0f
- override val carbonEmission: Double
+ override val carbonEmission: Float
get() = _carbonEmission
- private var _carbonEmission = 0.0
+ private var _carbonEmission = 0.0f
override val uptime: Long
get() = _uptime - previousUptime
@@ -382,7 +437,7 @@ public class ComputeMetricReader(
_energyUsage = hostSysStats.energyUsage
_carbonIntensity = carbonTrace.getCarbonIntensity(timestampAbsolute)
- _carbonEmission = carbonIntensity * (energyUsage / 3600000.0) // convert energy usage from J to kWh
+ _carbonEmission = carbonIntensity * (energyUsage / 3600000.0f) // convert energy usage from J to kWh
_uptime = hostSysStats.uptime.toMillis()
_downtime = hostSysStats.downtime.toMillis()
_bootTime = hostSysStats.bootTime
@@ -398,7 +453,7 @@ public class ComputeMetricReader(
previousCpuIdleTime = _cpuIdleTime
previousCpuStealTime = _cpuStealTime
previousCpuLostTime = _cpuLostTime
- previousPowerTotal = _energyUsage
+ previousEnergyUsage = _energyUsage
previousUptime = _uptime
previousDowntime = _downtime
@@ -407,15 +462,15 @@ public class ComputeMetricReader(
_guestsError = 0
_guestsInvalid = 0
- _cpuLimit = 0.0
- _cpuUsage = 0.0
- _cpuDemand = 0.0
- _cpuUtilization = 0.0
+ _cpuLimit = 0.0f
+ _cpuUsage = 0.0f
+ _cpuDemand = 0.0f
+ _cpuUtilization = 0.0f
- _powerDraw = 0.0
- _energyUsage = 0.0
- _carbonIntensity = 0.0
- _carbonEmission = 0.0
+ _powerDraw = 0.0f
+ _energyUsage = 0.0f
+ _carbonIntensity = 0.0f
+ _carbonEmission = 0.0f
}
}
@@ -424,11 +479,15 @@ public class ComputeMetricReader(
*/
private class TaskTableReaderImpl(
private val service: ComputeService,
- private val task: Task,
+ private val task: ServiceTask,
private val startTime: Duration = Duration.ofMillis(0),
) : TaskTableReader {
override fun copy(): TaskTableReader {
- val newTaskTable = TaskTableReaderImpl(service, task)
+ val newTaskTable =
+ TaskTableReaderImpl(
+ service,
+ task,
+ )
newTaskTable.setValues(this)
return newTaskTable
@@ -451,6 +510,9 @@ public class ComputeMetricReader(
_bootTime = table.bootTime
_bootTimeAbsolute = table.bootTimeAbsolute
+ _creationTime = table.creationTime
+ _finishTime = table.finishTime
+
_taskState = table.taskState
}
@@ -463,8 +525,6 @@ public class ComputeMetricReader(
task.name,
"vm",
"x86",
- task.image.uid.toString(),
- task.image.name,
task.flavor.coreCount,
task.flavor.memorySize,
)
@@ -473,7 +533,7 @@ public class ComputeMetricReader(
* The [HostInfo] of the host on which the task is hosted.
*/
override var host: HostInfo? = null
- private var _host: Host? = null
+ private var _host: SimHost? = null
private var _timestamp = Instant.MIN
override val timestamp: Instant
@@ -501,9 +561,17 @@ public class ComputeMetricReader(
get() = _bootTime
private var _bootTime: Instant? = null
- override val cpuLimit: Double
+ override val creationTime: Instant?
+ get() = _creationTime
+ private var _creationTime: Instant? = null
+
+ override val finishTime: Instant?
+ get() = _finishTime
+ private var _finishTime: Instant? = null
+
+ override val cpuLimit: Float
get() = _cpuLimit
- private var _cpuLimit = 0.0
+ private var _cpuLimit = 0.0f
override val cpuActiveTime: Long
get() = _cpuActiveTime - previousCpuActiveTime
@@ -538,16 +606,16 @@ public class ComputeMetricReader(
*/
fun record(now: Instant) {
val newHost = service.lookupHost(task)
- if (newHost != null && newHost.uid != _host?.uid) {
+ if (newHost != null && newHost.getUid() != _host?.getUid()) {
_host = newHost
host =
HostInfo(
- newHost.uid.toString(),
- newHost.name,
+ newHost.getUid().toString(),
+ newHost.getName(),
"x86",
- newHost.model.coreCount,
- newHost.model.cpuCapacity,
- newHost.model.memoryCapacity,
+ newHost.getModel().coreCount,
+ newHost.getModel().cpuCapacity,
+ newHost.getModel().memoryCapacity,
)
}
@@ -557,7 +625,7 @@ public class ComputeMetricReader(
_timestamp = now
_timestampAbsolute = now + startTime
- _cpuLimit = cpuStats?.capacity ?: 0.0
+ _cpuLimit = cpuStats?.capacity ?: 0.0f
_cpuActiveTime = cpuStats?.activeTime ?: 0
_cpuIdleTime = cpuStats?.idleTime ?: 0
_cpuStealTime = cpuStats?.stealTime ?: 0
@@ -566,6 +634,8 @@ public class ComputeMetricReader(
_downtime = sysStats?.downtime?.toMillis() ?: 0
_provisionTime = task.launchedAt
_bootTime = sysStats?.bootTime
+ _creationTime = task.createdAt
+ _finishTime = task.finishedAt
_taskState = task.state
@@ -588,7 +658,7 @@ public class ComputeMetricReader(
previousCpuLostTime = _cpuLostTime
_host = null
- _cpuLimit = 0.0
+ _cpuLimit = 0.0f
}
}
}
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/ComputeMonitor.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMonitor.kt
index 1df058fb..534bcc09 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/ComputeMonitor.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/ComputeMonitor.kt
@@ -20,11 +20,11 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry
+package org.opendc.compute.simulator.telemetry
-import org.opendc.compute.telemetry.table.HostTableReader
-import org.opendc.compute.telemetry.table.ServiceTableReader
-import org.opendc.compute.telemetry.table.TaskTableReader
+import org.opendc.compute.simulator.telemetry.table.HostTableReader
+import org.opendc.compute.simulator.telemetry.table.ServiceTableReader
+import org.opendc.compute.simulator.telemetry.table.TaskTableReader
/**
* A monitor that tracks the metrics and events of the OpenDC Compute service.
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/ComputeExportConfig.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ComputeExportConfig.kt
index 161c0936..3f220ad1 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/ComputeExportConfig.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ComputeExportConfig.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.export.parquet
+package org.opendc.compute.simulator.telemetry.parquet
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
@@ -35,9 +35,9 @@ import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.jsonObject
import org.opendc.common.logger.logger
-import org.opendc.compute.telemetry.table.HostTableReader
-import org.opendc.compute.telemetry.table.ServiceTableReader
-import org.opendc.compute.telemetry.table.TaskTableReader
+import org.opendc.compute.simulator.telemetry.table.HostTableReader
+import org.opendc.compute.simulator.telemetry.table.ServiceTableReader
+import org.opendc.compute.simulator.telemetry.table.TaskTableReader
import org.opendc.trace.util.parquet.exporter.ColListSerializer
import org.opendc.trace.util.parquet.exporter.ExportColumn
import org.opendc.trace.util.parquet.exporter.Exportable
@@ -97,7 +97,7 @@ public data class ComputeExportConfig(
* columns for [HostTableReader], [TaskTableReader] and [ServiceTableReader].
*/
public val ALL_COLUMNS: ComputeExportConfig by lazy {
- loadDfltColumns()
+ ComputeExportConfig.Companion.loadDfltColumns()
ComputeExportConfig(
hostExportColumns = ExportColumn.getAllLoadedColumns(),
taskExportColumns = ExportColumn.getAllLoadedColumns(),
@@ -135,7 +135,7 @@ public data class ComputeExportConfig(
}
// Loads the default columns so that they are available for deserialization.
- loadDfltColumns()
+ ComputeExportConfig.Companion.loadDfltColumns()
val elem = jsonDec.decodeJsonElement().jsonObject
val hostFields: List<ExportColumn<HostTableReader>> = elem["hostExportColumns"].toFieldList()
@@ -153,21 +153,21 @@ public data class ComputeExportConfig(
encoder: Encoder,
value: ComputeExportConfig,
) {
- encoder.encodeStructure(descriptor) {
+ encoder.encodeStructure(ComputeExportConfig.Companion.ComputeExportConfigSerializer.descriptor) {
encodeSerializableElement(
- descriptor,
+ ComputeExportConfig.Companion.ComputeExportConfigSerializer.descriptor,
0,
ColListSerializer(columnSerializer<HostTableReader>()),
value.hostExportColumns.toList(),
)
encodeSerializableElement(
- descriptor,
+ ComputeExportConfig.Companion.ComputeExportConfigSerializer.descriptor,
1,
ColListSerializer(columnSerializer<TaskTableReader>()),
value.taskExportColumns.toList(),
)
encodeSerializableElement(
- descriptor,
+ ComputeExportConfig.Companion.ComputeExportConfigSerializer.descriptor,
2,
ColListSerializer(columnSerializer<ServiceTableReader>()),
value.serviceExportColumns.toList(),
@@ -184,7 +184,7 @@ private inline fun <reified T : Exportable> JsonElement?.toFieldList(): List<Exp
this?.let {
json.decodeFromJsonElement(ColListSerializer(columnSerializer<T>()), it)
}?.ifEmpty {
- ComputeExportConfig.LOG.warn(
+ ComputeExportConfig.Companion.LOG.warn(
"deserialized list of export columns for exportable ${T::class.simpleName} " +
"produced empty list, falling back to all loaded columns",
)
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/DfltHostExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt
index 261c5462..1b76da6b 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/DfltHostExportColumns.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltHostExportColumns.kt
@@ -20,16 +20,16 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.export.parquet
+package org.opendc.compute.simulator.telemetry.parquet
import org.apache.parquet.io.api.Binary
import org.apache.parquet.schema.LogicalTypeAnnotation
import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.BINARY
-import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.DOUBLE
+import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.FLOAT
import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT32
import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT64
import org.apache.parquet.schema.Types
-import org.opendc.compute.telemetry.table.HostTableReader
+import org.opendc.compute.simulator.telemetry.table.HostTableReader
import org.opendc.trace.util.parquet.exporter.ExportColumn
/**
@@ -106,22 +106,22 @@ public object DfltHostExportColumns {
public val CPU_LIMIT: ExportColumn<HostTableReader> =
ExportColumn(
- field = Types.required(DOUBLE).named("cpu_limit"),
+ field = Types.required(FLOAT).named("cpu_limit"),
) { it.cpuLimit }
public val CPU_USAGE: ExportColumn<HostTableReader> =
ExportColumn(
- field = Types.required(DOUBLE).named("cpu_usage"),
+ field = Types.required(FLOAT).named("cpu_usage"),
) { it.cpuUsage }
public val CPU_DEMAND: ExportColumn<HostTableReader> =
ExportColumn(
- field = Types.required(DOUBLE).named("cpu_demand"),
+ field = Types.required(FLOAT).named("cpu_demand"),
) { it.cpuDemand }
public val CPU_UTILIZATION: ExportColumn<HostTableReader> =
ExportColumn(
- field = Types.required(DOUBLE).named("cpu_utilization"),
+ field = Types.required(FLOAT).named("cpu_utilization"),
) { it.cpuUtilization }
public val CPU_TIME_ACTIVE: ExportColumn<HostTableReader> =
@@ -146,22 +146,22 @@ public object DfltHostExportColumns {
public val POWER_DRAW: ExportColumn<HostTableReader> =
ExportColumn(
- field = Types.required(DOUBLE).named("power_draw"),
+ field = Types.required(FLOAT).named("power_draw"),
) { it.powerDraw }
public val ENERGY_USAGE: ExportColumn<HostTableReader> =
ExportColumn(
- field = Types.required(DOUBLE).named("energy_usage"),
+ field = Types.required(FLOAT).named("energy_usage"),
) { it.energyUsage }
public val CARBON_INTENSITY: ExportColumn<HostTableReader> =
ExportColumn(
- field = Types.required(DOUBLE).named("carbon_intensity"),
+ field = Types.required(FLOAT).named("carbon_intensity"),
) { it.carbonIntensity }
public val CARBON_EMISSION: ExportColumn<HostTableReader> =
ExportColumn(
- field = Types.required(DOUBLE).named("carbon_emission"),
+ field = Types.required(FLOAT).named("carbon_emission"),
) { it.carbonEmission }
public val UP_TIME: ExportColumn<HostTableReader> =
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/DfltServiceExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltServiceExportColumns.kt
index 8038060d..aa08e8ff 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/DfltServiceExportColumns.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltServiceExportColumns.kt
@@ -20,12 +20,12 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.export.parquet
+package org.opendc.compute.simulator.telemetry.parquet
import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT32
import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT64
import org.apache.parquet.schema.Types
-import org.opendc.compute.telemetry.table.ServiceTableReader
+import org.opendc.compute.simulator.telemetry.table.ServiceTableReader
import org.opendc.trace.util.parquet.exporter.ExportColumn
/**
@@ -64,26 +64,36 @@ public object DfltServiceExportColumns {
field = Types.required(INT32).named("tasks_pending"),
) { it.tasksPending }
+ public val TASKS_TOTAL: ExportColumn<ServiceTableReader> =
+ ExportColumn(
+ field = Types.required(INT32).named("tasks_total"),
+ ) { it.tasksTotal }
+
public val TASKS_ACTIVE: ExportColumn<ServiceTableReader> =
ExportColumn(
field = Types.required(INT32).named("tasks_active"),
) { it.tasksActive }
+ public val TASKS_COMPLETED: ExportColumn<ServiceTableReader> =
+ ExportColumn(
+ field = Types.required(INT32).named("tasks_completed"),
+ ) { it.tasksCompleted }
+
+ public val TASKS_FAILED: ExportColumn<ServiceTableReader> =
+ ExportColumn(
+ field = Types.required(INT32).named("tasks_terminated"),
+ ) { it.tasksTerminated }
+
public val ATTEMPTS_SUCCESS: ExportColumn<ServiceTableReader> =
ExportColumn(
field = Types.required(INT32).named("attempts_success"),
) { it.attemptsSuccess }
- public val AT3yyTEMPTS_FAILURE: ExportColumn<ServiceTableReader> =
+ public val ATTEMPTS_FAILURE: ExportColumn<ServiceTableReader> =
ExportColumn(
field = Types.required(INT32).named("attempts_failure"),
) { it.attemptsFailure }
- public val ATTEMPTS_ERROR: ExportColumn<ServiceTableReader> =
- ExportColumn(
- field = Types.required(INT32).named("attempts_error"),
- ) { it.attemptsError }
-
/**
* The columns that are always included in the output file.
*/
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/DfltTaskExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt
index 9e86e1a3..6658e444 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/DfltTaskExportColumns.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt
@@ -20,16 +20,16 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.export.parquet
+package org.opendc.compute.simulator.telemetry.parquet
import org.apache.parquet.io.api.Binary
import org.apache.parquet.schema.LogicalTypeAnnotation
import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.BINARY
-import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.DOUBLE
+import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.FLOAT
import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT32
import org.apache.parquet.schema.PrimitiveType.PrimitiveTypeName.INT64
import org.apache.parquet.schema.Types
-import org.opendc.compute.telemetry.table.TaskTableReader
+import org.opendc.compute.simulator.telemetry.table.TaskTableReader
import org.opendc.trace.util.parquet.exporter.ExportColumn
/**
@@ -94,7 +94,7 @@ public object DfltTaskExportColumns {
public val CPU_LIMIT: ExportColumn<TaskTableReader> =
ExportColumn(
- field = Types.required(DOUBLE).named("cpu_limit"),
+ field = Types.required(FLOAT).named("cpu_limit"),
) { it.cpuLimit }
public val CPU_TIME_ACTIVE: ExportColumn<TaskTableReader> =
@@ -137,6 +137,16 @@ public object DfltTaskExportColumns {
field = Types.optional(INT64).named("boot_time"),
) { it.bootTime?.toEpochMilli() }
+ public val CREATION_TIME: ExportColumn<TaskTableReader> =
+ ExportColumn(
+ field = Types.optional(INT64).named("creation_time"),
+ ) { it.creationTime?.toEpochMilli() }
+
+ public val FINISH_TIME: ExportColumn<TaskTableReader> =
+ ExportColumn(
+ field = Types.optional(INT64).named("finish_time"),
+ ) { it.finishTime?.toEpochMilli() }
+
public val BOOT_TIME_ABS: ExportColumn<TaskTableReader> =
ExportColumn(
field = Types.optional(INT64).named("boot_time_absolute"),
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/ParquetComputeMonitor.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ParquetComputeMonitor.kt
index 3b7a7c0c..4cd920c4 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/ParquetComputeMonitor.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/ParquetComputeMonitor.kt
@@ -20,12 +20,12 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.export.parquet
+package org.opendc.compute.simulator.telemetry.parquet
-import org.opendc.compute.telemetry.ComputeMonitor
-import org.opendc.compute.telemetry.table.HostTableReader
-import org.opendc.compute.telemetry.table.ServiceTableReader
-import org.opendc.compute.telemetry.table.TaskTableReader
+import org.opendc.compute.simulator.telemetry.ComputeMonitor
+import org.opendc.compute.simulator.telemetry.table.HostTableReader
+import org.opendc.compute.simulator.telemetry.table.ServiceTableReader
+import org.opendc.compute.simulator.telemetry.table.TaskTableReader
import org.opendc.trace.util.parquet.exporter.ExportColumn
import org.opendc.trace.util.parquet.exporter.Exportable
import org.opendc.trace.util.parquet.exporter.Exporter
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/README.md b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/README.md
index aee63fc9..3baafed4 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/export/parquet/README.md
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/README.md
@@ -8,9 +8,9 @@ The 'default' columns are defined in `DfltHostExportcolumns`, `DfltTaskExportCol
Each `ExportColumn` has a `Regex`, used for deserialization. If no custom regex is provided, the default one is used. The default regex matches the column name in case-insensitive manner, either with `_` as in the name or with ` ` (blank space).
###### E.g.:
-***column name*** = "cpu\_count"
-***default column regex*** = "\\s*(?:cpu_count|cpu count)\\s*" (case insensitive)
-***matches*** = "cpu\_count", "cpu count", "CpU/_cOuNt" etc.
+***column name*** = "cpuModel\_count"
+***default column regex*** = "\\s*(?:cpu_count|cpuModel count)\\s*" (case insensitive)
+***matches*** = "cpuModel\_count", "cpuModel count", "CpU/_cOuNt" etc.
### JSON Schema
```json
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/HostInfo.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostInfo.kt
index 62b7ef0d..1f1b9522 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/HostInfo.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostInfo.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.table
+package org.opendc.compute.simulator.telemetry.table
/**
* Information about a host exposed to the telemetry service.
@@ -30,6 +30,6 @@ public data class HostInfo(
val name: String,
val arch: String,
val coreCount: Int,
- val coreSpeed: Double,
+ val coreSpeed: Float,
val memCapacity: Long,
)
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/HostTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt
index a7b8bedb..5f09e7f5 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/HostTableReader.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/HostTableReader.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.table
+package org.opendc.compute.simulator.telemetry.table
import org.opendc.trace.util.parquet.exporter.Exportable
import java.time.Instant
@@ -71,22 +71,22 @@ public interface HostTableReader : Exportable {
/**
* The capacity of the CPUs in the host (in MHz).
*/
- public val cpuLimit: Double
+ public val cpuLimit: Float
/**
* The usage of all CPUs in the host (in MHz).
*/
- public val cpuUsage: Double
+ public val cpuUsage: Float
/**
* The demand of all vCPUs of the guests (in MHz)
*/
- public val cpuDemand: Double
+ public val cpuDemand: Float
/**
* The CPU utilization of the host.
*/
- public val cpuUtilization: Double
+ public val cpuUtilization: Float
/**
* The duration (in ms) that a CPU was active in the host.
@@ -111,22 +111,22 @@ public interface HostTableReader : Exportable {
/**
* The current power draw of the host in W.
*/
- public val powerDraw: Double
+ public val powerDraw: Float
/**
* The total energy consumption of the host since last sample in J.
*/
- public val energyUsage: Double
+ public val energyUsage: Float
/**
* The current carbon intensity of the host in gCO2 / kW.
*/
- public val carbonIntensity: Double
+ public val carbonIntensity: Float
/**
* The current carbon emission since the last deadline in g.
*/
- public val carbonEmission: Double
+ public val carbonEmission: Float
/**
* The uptime of the host since last time in ms.
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/ServiceData.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceData.kt
index 7a8ba6a7..16c38297 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/ServiceData.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceData.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.table
+package org.opendc.compute.simulator.telemetry.table
import java.time.Instant
@@ -35,8 +35,7 @@ public data class ServiceData(
val tasksPending: Int,
val tasksActive: Int,
val attemptsSuccess: Int,
- val attemptsFailure: Int,
- val attemptsError: Int,
+ val attemptsTerminated: Int,
)
/**
@@ -52,6 +51,5 @@ public fun ServiceTableReader.toServiceData(): ServiceData {
tasksActive,
attemptsSuccess,
attemptsFailure,
- attemptsError,
)
}
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/ServiceTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReader.kt
index 23630fb4..690dfe0a 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/ServiceTableReader.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/ServiceTableReader.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.table
+package org.opendc.compute.simulator.telemetry.table
import org.opendc.trace.util.parquet.exporter.Exportable
import java.time.Instant
@@ -69,6 +69,16 @@ public interface ServiceTableReader : Exportable {
public val tasksActive: Int
/**
+ * The number of tasks that completed the tasks successfully
+ */
+ public val tasksCompleted: Int
+
+ /**
+ * The number of tasks that failed more times than allowed and are thus terminated
+ */
+ public val tasksTerminated: Int
+
+ /**
* The scheduling attempts that were successful.
*/
public val attemptsSuccess: Int
@@ -77,9 +87,4 @@ public interface ServiceTableReader : Exportable {
* The scheduling attempts that were unsuccessful due to client error.
*/
public val attemptsFailure: Int
-
- /**
- * The scheduling attempts that were unsuccessful due to scheduler error.
- */
- public val attemptsError: Int
}
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/TaskInfo.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskInfo.kt
index 2d1ae91a..6ff56541 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/TaskInfo.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskInfo.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.table
+package org.opendc.compute.simulator.telemetry.table
/**
* Static information about a task exposed to the telemetry service.
@@ -30,8 +30,6 @@ public data class TaskInfo(
val name: String,
val type: String,
val arch: String,
- val imageId: String,
- val imageName: String,
val cpuCount: Int,
val memCapacity: Long,
)
diff --git a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/TaskTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReader.kt
index ae7f7a49..bc6a4edd 100644
--- a/opendc-compute/opendc-compute-telemetry/src/main/kotlin/org/opendc/compute/telemetry/table/TaskTableReader.kt
+++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/TaskTableReader.kt
@@ -20,10 +20,10 @@
* SOFTWARE.
*/
-package org.opendc.compute.telemetry.table
+package org.opendc.compute.simulator.telemetry.table
import org.opendc.compute.api.TaskState
-import org.opendc.compute.telemetry.export.parquet.DfltTaskExportColumns
+import org.opendc.compute.simulator.telemetry.parquet.DfltTaskExportColumns
import org.opendc.trace.util.parquet.exporter.Exportable
import java.time.Instant
@@ -81,9 +81,19 @@ public interface TaskTableReader : Exportable {
public val bootTimeAbsolute: Instant?
/**
+ * The [Instant] at which the task booted relative to the start of the workload.
+ */
+ public val creationTime: Instant?
+
+ /**
+ * The [Instant] at which the task booted relative to the start of the workload.
+ */
+ public val finishTime: Instant?
+
+ /**
* The capacity of the CPUs of Host on which the task is running (in MHz).
*/
- public val cpuLimit: Double
+ public val cpuLimit: Float
/**
* The duration (in seconds) that a CPU was active in the task.
diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt
deleted file mode 100644
index b5bc66a9..00000000
--- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt
+++ /dev/null
@@ -1,393 +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
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.suspendCancellableCoroutine
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertAll
-import org.opendc.compute.api.Flavor
-import org.opendc.compute.api.Image
-import org.opendc.compute.api.Task
-import org.opendc.compute.api.TaskState
-import org.opendc.compute.api.TaskWatcher
-import org.opendc.compute.service.driver.Host
-import org.opendc.compute.service.driver.HostListener
-import org.opendc.simulator.compute.SimBareMetalMachine
-import org.opendc.simulator.compute.kernel.SimHypervisor
-import org.opendc.simulator.compute.model.Cpu
-import org.opendc.simulator.compute.model.MachineModel
-import org.opendc.simulator.compute.model.MemoryUnit
-import org.opendc.simulator.compute.workload.SimTrace
-import org.opendc.simulator.compute.workload.SimTraceFragment
-import org.opendc.simulator.flow2.FlowEngine
-import org.opendc.simulator.flow2.mux.FlowMultiplexerFactory
-import org.opendc.simulator.kotlin.runSimulation
-import java.time.Instant
-import java.util.SplittableRandom
-import java.util.UUID
-import kotlin.coroutines.resume
-
-/**
- * Basic test-suite for the hypervisor.
- */
-internal class SimHostTest {
- private lateinit var machineModel: MachineModel
-
- @BeforeEach
- fun setUp() {
- machineModel =
- MachineModel(
- Cpu(
- 0,
- 2,
- 3200.0,
- "Intel",
- "Xeon",
- "amd64",
- ),
- // memory
- MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000 * 4),
- )
- }
-
- /**
- * Test a single virtual machine hosted by the hypervisor.
- */
- @Test
- fun testSingle() =
- runSimulation {
- val duration = 5 * 60L
-
- val engine = FlowEngine.create(dispatcher)
- val graph = engine.newGraph()
-
- val machine = SimBareMetalMachine.create(graph, machineModel)
- val hypervisor = SimHypervisor.create(FlowMultiplexerFactory.maxMinMultiplexer(), SplittableRandom(1))
-
- val host =
- SimHost(
- uid = UUID.randomUUID(),
- name = "test",
- meta = emptyMap(),
- timeSource,
- machine,
- hypervisor,
- )
- val vmImage =
- MockImage(
- UUID.randomUUID(),
- "<unnamed>",
- emptyMap(),
- mapOf(
- "workload" to
- SimTrace.ofFragments(
- SimTraceFragment(0, duration * 1000, 0.0, 2),
- SimTraceFragment(duration * 1000, duration * 1000, 3200.0, 2),
- SimTraceFragment(duration * 2000, duration * 1000, 0.0, 2),
- SimTraceFragment(duration * 3000, duration * 1000, 6500.0, 2),
- ).createWorkload(0),
- ),
- )
-
- val flavor = MockFlavor(2, 0)
-
- suspendCancellableCoroutine { cont ->
- host.addListener(
- object : HostListener {
- private var finished = 0
-
- override fun onStateChanged(
- host: Host,
- task: Task,
- newState: TaskState,
- ) {
- if (newState == TaskState.TERMINATED && ++finished == 1) {
- cont.resume(Unit)
- }
- }
- },
- )
- val server = MockTask(UUID.randomUUID(), "a", flavor, vmImage)
- host.spawn(server)
- host.start(server)
- }
-
- // Ensure last cycle is collected
-// delay(1000L * duration)
- host.close()
-
- val cpuStats = host.getCpuStats()
-
- assertAll(
- { assertEquals(450000, cpuStats.activeTime, "Active time does not match") },
- { assertEquals(750000, cpuStats.idleTime, "Idle time does not match") },
- { assertEquals(4688, cpuStats.stealTime, "Steal time does not match") },
- { assertEquals(1200000, timeSource.millis()) },
- )
- }
-
- /**
- * Test overcommitting of resources by the hypervisor.
- */
- @Test
- fun testOvercommitted() =
- runSimulation {
- val duration = 5 * 60L
-
- val engine = FlowEngine.create(dispatcher)
- val graph = engine.newGraph()
-
- val machine = SimBareMetalMachine.create(graph, machineModel)
- val hypervisor = SimHypervisor.create(FlowMultiplexerFactory.maxMinMultiplexer(), SplittableRandom(1))
-
- val host =
- SimHost(
- uid = UUID.randomUUID(),
- name = "test",
- meta = emptyMap(),
- timeSource,
- machine,
- hypervisor,
- )
- val vmImageA =
- MockImage(
- UUID.randomUUID(),
- "<unnamed>",
- emptyMap(),
- mapOf(
- "workload" to
- SimTrace.ofFragments(
- SimTraceFragment(0, duration * 1000, 0.0, 2),
- SimTraceFragment(duration * 1000, duration * 1000, 3200.0, 2),
- SimTraceFragment(duration * 2000, duration * 1000, 0.0, 2),
- SimTraceFragment(duration * 3000, duration * 1000, 6500.0, 2),
- ).createWorkload(0),
- ),
- )
- val vmImageB =
- MockImage(
- UUID.randomUUID(),
- "<unnamed>",
- emptyMap(),
- mapOf(
- "workload" to
- SimTrace.ofFragments(
- SimTraceFragment(0, duration * 1000, 0.0, 2),
- SimTraceFragment(duration * 1000, duration * 1000, 3200.0, 2),
- SimTraceFragment(duration * 2000, duration * 1000, 0.0, 2),
- SimTraceFragment(duration * 3000, duration * 1000, 6500.0, 2),
- ).createWorkload(0),
- ),
- )
-
- val flavor = MockFlavor(2, 0)
-
- coroutineScope {
- suspendCancellableCoroutine { cont ->
- host.addListener(
- object : HostListener {
- private var finished = 0
-
- override fun onStateChanged(
- host: Host,
- task: Task,
- newState: TaskState,
- ) {
- if (newState == TaskState.TERMINATED && ++finished == 2) {
- cont.resume(Unit)
- }
- }
- },
- )
- val serverA = MockTask(UUID.randomUUID(), "a", flavor, vmImageA)
- host.spawn(serverA)
- val serverB = MockTask(UUID.randomUUID(), "b", flavor, vmImageB)
- host.spawn(serverB)
-
- host.start(serverA)
- host.start(serverB)
- }
- }
-
- // Ensure last cycle is collected
- delay(1000L * duration)
- host.close()
-
- val cpuStats = host.getCpuStats()
-
- assertAll(
- { assertEquals(600000, cpuStats.activeTime, "Active time does not match") },
- { assertEquals(900000, cpuStats.idleTime, "Idle time does not match") },
- { assertEquals(309375, cpuStats.stealTime, "Steal time does not match") },
- { assertEquals(1500000, timeSource.millis()) },
- )
- }
-
- /**
- * Test failure of the host.
- */
- @Test
- fun testFailure() =
- runSimulation {
- val duration = 5 * 60L
-
- val engine = FlowEngine.create(dispatcher)
- val graph = engine.newGraph()
-
- val machine = SimBareMetalMachine.create(graph, machineModel)
- val hypervisor = SimHypervisor.create(FlowMultiplexerFactory.maxMinMultiplexer(), SplittableRandom(1))
- val host =
- SimHost(
- uid = UUID.randomUUID(),
- name = "test",
- meta = emptyMap(),
- timeSource,
- machine,
- hypervisor,
- )
- val image =
- MockImage(
- UUID.randomUUID(),
- "<unnamed>",
- emptyMap(),
- mapOf(
- "workload" to
- SimTrace.ofFragments(
- SimTraceFragment(0, duration * 1000, 0.0, 2),
- SimTraceFragment(duration * 1000, duration * 1000, 3200.0, 2),
- SimTraceFragment(duration * 2000, duration * 1000, 0.0, 2),
- SimTraceFragment(duration * 3000, duration * 1000, 6500.0, 2),
- ).createWorkload(0),
- ),
- )
- val flavor = MockFlavor(2, 0)
- val server = MockTask(UUID.randomUUID(), "a", flavor, image)
-
- coroutineScope {
- host.spawn(server)
- host.start(server)
- delay(5000L)
- host.fail()
- delay(duration * 1000)
- host.recover()
-
- suspendCancellableCoroutine { cont ->
- host.addListener(
- object : HostListener {
- override fun onStateChanged(
- host: Host,
- task: Task,
- newState: TaskState,
- ) {
- if (newState == TaskState.TERMINATED) {
- cont.resume(Unit)
- }
- }
- },
- )
- }
- }
-
- host.close()
- // Ensure last cycle is collected
- delay(1000L * duration)
-
- val cpuStats = host.getCpuStats()
- val sysStats = host.getSystemStats()
- val guestSysStats = host.getSystemStats(server)
-
- assertAll(
- { assertEquals(755000, cpuStats.idleTime, "Idle time does not match") },
- { assertEquals(450000, cpuStats.activeTime, "Active time does not match") },
- { assertEquals(1205000, sysStats.uptime.toMillis(), "Uptime does not match") },
- { assertEquals(300000, sysStats.downtime.toMillis(), "Downtime does not match") },
- { assertEquals(1205000, guestSysStats.uptime.toMillis(), "Guest uptime does not match") },
- { assertEquals(300000, guestSysStats.downtime.toMillis(), "Guest downtime does not match") },
- )
- }
-
- private class MockFlavor(
- override val coreCount: Int,
- override val memorySize: Long,
- ) : Flavor {
- override val uid: UUID = UUID.randomUUID()
- override val name: String = "test"
- override val labels: Map<String, String> = emptyMap()
- override val meta: Map<String, Any> = emptyMap()
-
- override fun delete() {
- throw NotImplementedError()
- }
-
- override fun reload() {
- throw NotImplementedError()
- }
- }
-
- private class MockImage(
- override val uid: UUID,
- override val name: String,
- override val labels: Map<String, String>,
- override val meta: Map<String, Any>,
- ) : Image {
- override fun delete() {
- throw NotImplementedError()
- }
-
- override fun reload() {
- throw NotImplementedError()
- }
- }
-
- private class MockTask(
- override val uid: UUID,
- override val name: String,
- override val flavor: Flavor,
- override val image: Image,
- override val numFailures: Int = 10,
- ) : Task {
- override val labels: Map<String, String> = emptyMap()
-
- override val meta: Map<String, Any> = emptyMap()
-
- override val state: TaskState = TaskState.TERMINATED
-
- override val launchedAt: Instant? = null
-
- override fun start() {}
-
- override fun stop() {}
-
- override fun delete() {}
-
- override fun watch(watcher: TaskWatcher) {}
-
- override fun unwatch(watcher: TaskWatcher) {}
-
- override fun reload() {}
- }
-}
diff --git a/opendc-compute/opendc-compute-telemetry/build.gradle.kts b/opendc-compute/opendc-compute-telemetry/build.gradle.kts
deleted file mode 100644
index e8692449..00000000
--- a/opendc-compute/opendc-compute-telemetry/build.gradle.kts
+++ /dev/null
@@ -1,44 +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.
- */
-
-description = "OpenDC Compute Service implementation"
-
-// Build configuration
-plugins {
- `kotlin-library-conventions`
- kotlin("plugin.serialization") version "1.9.22"
-}
-
-dependencies {
- api(projects.opendcCompute.opendcComputeApi)
- api(projects.opendcTrace.opendcTraceParquet)
- implementation(projects.opendcCommon)
- implementation(libs.kotlin.logging)
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
- implementation(project(mapOf("path" to ":opendc-trace:opendc-trace-parquet")))
- implementation(project(mapOf("path" to ":opendc-compute:opendc-compute-service")))
- implementation(project(mapOf("path" to ":opendc-compute:opendc-compute-carbon")))
-
- testImplementation(projects.opendcSimulator.opendcSimulatorCore)
- testRuntimeOnly(libs.log4j.core)
- testRuntimeOnly(libs.log4j.slf4j)
-}
diff --git a/opendc-compute/opendc-compute-telemetry/src/test/resources/log4j2.xml b/opendc-compute/opendc-compute-telemetry/src/test/resources/log4j2.xml
deleted file mode 100644
index 0dfb75f2..00000000
--- a/opendc-compute/opendc-compute-telemetry/src/test/resources/log4j2.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt
index e0fba34f..9e637b1b 100644
--- a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt
+++ b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt
@@ -28,11 +28,10 @@ import org.opendc.compute.topology.specs.ClusterSpec
import org.opendc.compute.topology.specs.HostJSONSpec
import org.opendc.compute.topology.specs.HostSpec
import org.opendc.compute.topology.specs.TopologySpec
-import org.opendc.simulator.compute.SimPsuFactories
-import org.opendc.simulator.compute.model.Cpu
-import org.opendc.simulator.compute.model.MachineModel
-import org.opendc.simulator.compute.model.MemoryUnit
-import org.opendc.simulator.compute.power.getPowerModel
+import org.opendc.simulator.compute.cpu.getPowerModel
+import org.opendc.simulator.compute.models.CpuModel
+import org.opendc.simulator.compute.models.MachineModel
+import org.opendc.simulator.compute.models.MemoryUnit
import java.io.File
import java.io.InputStream
import java.util.SplittableRandom
@@ -120,10 +119,10 @@ private fun HostJSONSpec.toHostSpecs(
): HostSpec {
val units =
List(cpu.count) {
- Cpu(
+ CpuModel(
globalCoreId++,
cpu.coreCount,
- cpu.coreSpeed.toMHz(),
+ cpu.coreSpeed.toMHz().toFloat(),
)
}
@@ -150,7 +149,7 @@ private fun HostJSONSpec.toHostSpecs(
hostName,
mapOf("cluster" to clusterId),
machineModel,
- SimPsuFactories.simple(powerModel),
+ powerModel,
)
hostId++
diff --git a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/HostSpec.kt b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/HostSpec.kt
index 9857f70a..1956ffde 100644
--- a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/HostSpec.kt
+++ b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/HostSpec.kt
@@ -22,10 +22,8 @@
package org.opendc.compute.topology.specs
-import org.opendc.simulator.compute.SimPsuFactories
-import org.opendc.simulator.compute.SimPsuFactory
-import org.opendc.simulator.compute.model.MachineModel
-import org.opendc.simulator.flow2.mux.FlowMultiplexerFactory
+import org.opendc.simulator.compute.cpu.CpuPowerModel
+import org.opendc.simulator.compute.models.MachineModel
import java.util.UUID
/**
@@ -35,7 +33,7 @@ import java.util.UUID
* @param name The name of the host.
* @param meta The metadata of the host.
* @param model The physical model of the machine.
- * @param psuFactory The [SimPsuFactory] to construct the PSU that models the power consumption of the machine.
+ * @param cpuPowerModel The [SimPsuFactory] to construct the PSU that models the power consumption of the machine.
* @param multiplexerFactory The [FlowMultiplexerFactory] that is used to multiplex the virtual machines over the host.
*/
public data class HostSpec(
@@ -43,6 +41,5 @@ public data class HostSpec(
val name: String,
val meta: Map<String, Any>,
val model: MachineModel,
- val psuFactory: SimPsuFactory = SimPsuFactories.noop(),
- val multiplexerFactory: FlowMultiplexerFactory = FlowMultiplexerFactory.maxMinMultiplexer(),
+ val cpuPowerModel: CpuPowerModel,
)
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt
index c9f784ff..9516c56e 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt
+++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkload.kt
@@ -29,10 +29,10 @@ import java.util.random.RandomGenerator
*/
public interface ComputeWorkload {
/**
- * Resolve the workload into a list of [VirtualMachine]s to simulate.
+ * Resolve the workload into a list of [Task]s to simulate.
*/
public fun resolve(
loader: ComputeWorkloadLoader,
random: RandomGenerator,
- ): List<VirtualMachine>
+ ): List<Task>
}
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt
index 99863af8..f22bc1d1 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt
+++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt
@@ -23,13 +23,8 @@
package org.opendc.compute.workload
import mu.KotlinLogging
-import org.opendc.simulator.compute.kernel.interference.VmInterferenceModel
-import org.opendc.simulator.compute.workload.SimTrace
+import org.opendc.simulator.compute.workload.TraceWorkload
import org.opendc.trace.Trace
-import org.opendc.trace.conv.INTERFERENCE_GROUP_MEMBERS
-import org.opendc.trace.conv.INTERFERENCE_GROUP_SCORE
-import org.opendc.trace.conv.INTERFERENCE_GROUP_TARGET
-import org.opendc.trace.conv.TABLE_INTERFERENCE_GROUPS
import org.opendc.trace.conv.TABLE_RESOURCES
import org.opendc.trace.conv.TABLE_RESOURCE_STATES
import org.opendc.trace.conv.resourceCpuCapacity
@@ -52,7 +47,12 @@ import kotlin.math.roundToLong
*
* @param baseDir The directory containing the traces.
*/
-public class ComputeWorkloadLoader(private val baseDir: File) {
+public class ComputeWorkloadLoader(
+ private val baseDir: File,
+ private val checkpointInterval: Long,
+ private val checkpointDuration: Long,
+ private val checkpointIntervalScaling: Double,
+) {
/**
* The logger for this instance.
*/
@@ -61,7 +61,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
/**
* The cache of workloads.
*/
- private val cache = ConcurrentHashMap<String, SoftReference<List<VirtualMachine>>>()
+ private val cache = ConcurrentHashMap<String, SoftReference<List<Task>>>()
/**
* Read the fragments into memory.
@@ -83,7 +83,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
val cores = reader.getInt(coresCol)
val cpuUsage = reader.getDouble(usageCol)
- val builder = fragments.computeIfAbsent(id) { Builder() }
+ val builder = fragments.computeIfAbsent(id) { Builder(checkpointInterval, checkpointDuration, checkpointIntervalScaling) }
builder.add(durationMs, cpuUsage, cores)
}
@@ -99,8 +99,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
private fun parseMeta(
trace: Trace,
fragments: Map<String, Builder>,
- interferenceModel: VmInterferenceModel,
- ): List<VirtualMachine> {
+ ): List<Task> {
val reader = checkNotNull(trace.getTable(TABLE_RESOURCES)).newReader()
val idCol = reader.resolve(resourceID)
@@ -111,7 +110,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
val memCol = reader.resolve(resourceMemCapacity)
var counter = 0
- val entries = mutableListOf<VirtualMachine>()
+ val entries = mutableListOf<Task>()
return try {
while (reader.nextRow()) {
@@ -131,7 +130,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
val totalLoad = builder.totalLoad
entries.add(
- VirtualMachine(
+ Task(
uid,
id,
cpuCount,
@@ -141,13 +140,12 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
submissionTime,
duration,
builder.build(),
- interferenceModel.getProfile(id),
),
)
}
// Make sure the virtual machines are ordered by start time
- entries.sortBy { it.startTime }
+ entries.sortBy { it.submissionTime }
entries
} catch (e: Exception) {
@@ -159,40 +157,12 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
}
/**
- * Read the interference model associated with the specified [trace].
- */
- private fun parseInterferenceModel(trace: Trace): VmInterferenceModel {
- val reader = checkNotNull(trace.getTable(TABLE_INTERFERENCE_GROUPS)).newReader()
-
- return try {
- val membersCol = reader.resolve(INTERFERENCE_GROUP_MEMBERS)
- val targetCol = reader.resolve(INTERFERENCE_GROUP_TARGET)
- val scoreCol = reader.resolve(INTERFERENCE_GROUP_SCORE)
-
- val modelBuilder = VmInterferenceModel.builder()
-
- while (reader.nextRow()) {
- val members = reader.getSet(membersCol, String::class.java)!!
- val target = reader.getDouble(targetCol)
- val score = reader.getDouble(scoreCol)
-
- modelBuilder
- .addGroup(members, target, score)
- }
-
- modelBuilder.build()
- } finally {
- reader.close()
- }
- }
-
- /**
* Load the trace with the specified [name] and [format].
*/
public fun get(
name: String,
format: String,
- ): List<VirtualMachine> {
+ ): List<Task> {
val ref =
cache.compute(name) { key, oldVal ->
val inst = oldVal?.get()
@@ -203,8 +173,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
val trace = Trace.open(path, format)
val fragments = parseFragments(trace)
- val interferenceModel = parseInterferenceModel(trace)
- val vms = parseMeta(trace, fragments, interferenceModel)
+ val vms = parseMeta(trace, fragments)
SoftReference(vms)
} else {
@@ -225,7 +194,7 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
/**
* A builder for a VM trace.
*/
- private class Builder {
+ private class Builder(checkpointInterval: Long, checkpointDuration: Long, checkpointIntervalScaling: Double) {
/**
* The total load of the trace.
*/
@@ -234,13 +203,12 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
/**
* The internal builder for the trace.
*/
- private val builder = SimTrace.builder()
+ private val builder = TraceWorkload.builder(checkpointInterval, checkpointDuration, checkpointIntervalScaling)
/**
* Add a fragment to the trace.
*
- * @param timestamp Timestamp at which the fragment starts (in epoch millis).
- * @param deadline Timestamp at which the fragment ends (in epoch millis).
+ * @param duration The duration of the fragment (in epoch millis).
* @param usage CPU usage of this fragment.
* @param cores Number of cores used.
*/
@@ -257,6 +225,6 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
/**
* Build the trace.
*/
- fun build(): SimTrace = builder.build()
+ fun build(): TraceWorkload = builder.build()
}
}
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/Task.kt
index 66d51127..d121b381 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/Task.kt
@@ -22,8 +22,7 @@
package org.opendc.compute.workload
-import org.opendc.simulator.compute.kernel.interference.VmInterferenceProfile
-import org.opendc.simulator.compute.workload.SimTrace
+import org.opendc.simulator.compute.workload.TraceWorkload
import java.time.Instant
import java.util.UUID
@@ -35,20 +34,18 @@ import java.util.UUID
* @param cpuCapacity The required CPU capacity for the VM in MHz.
* @param cpuCount The number of vCPUs in the VM.
* @param memCapacity The provisioned memory for the VM in MB.
- * @param startTime The start time of the VM.
- * @param stopTime The stop time of the VM.
+ * @param submissionTime The start time of the VM.
* @param trace The trace that belong to this VM.
* @param interferenceProfile The interference profile of this virtual machine.
*/
-public data class VirtualMachine(
+public data class Task(
val uid: UUID,
val name: String,
val cpuCount: Int,
val cpuCapacity: Double,
val memCapacity: Long,
val totalLoad: Double,
- val startTime: Instant,
+ val submissionTime: Instant,
val duration: Long,
- val trace: SimTrace,
- val interferenceProfile: VmInterferenceProfile?,
+ val trace: TraceWorkload,
)
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt
index aba493b6..998dbb34 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt
+++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/CompositeComputeWorkload.kt
@@ -25,7 +25,7 @@ package org.opendc.compute.workload.internal
import mu.KotlinLogging
import org.opendc.compute.workload.ComputeWorkload
import org.opendc.compute.workload.ComputeWorkloadLoader
-import org.opendc.compute.workload.VirtualMachine
+import org.opendc.compute.workload.Task
import java.util.random.RandomGenerator
/**
@@ -40,12 +40,12 @@ internal class CompositeComputeWorkload(val sources: Map<ComputeWorkload, Double
override fun resolve(
loader: ComputeWorkloadLoader,
random: RandomGenerator,
- ): List<VirtualMachine> {
+ ): List<Task> {
val traces = sources.map { (source, fraction) -> fraction to source.resolve(loader, random) }
val totalLoad = traces.sumOf { (_, vms) -> vms.sumOf { it.totalLoad } }
- val res = mutableListOf<VirtualMachine>()
+ val res = mutableListOf<Task>()
for ((fraction, vms) in traces) {
var currentLoad = 0.0
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt
index 4207b2be..d3bdde31 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt
+++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/HpcSampledComputeWorkload.kt
@@ -25,7 +25,7 @@ package org.opendc.compute.workload.internal
import mu.KotlinLogging
import org.opendc.compute.workload.ComputeWorkload
import org.opendc.compute.workload.ComputeWorkloadLoader
-import org.opendc.compute.workload.VirtualMachine
+import org.opendc.compute.workload.Task
import java.util.UUID
import java.util.random.RandomGenerator
@@ -53,7 +53,7 @@ internal class HpcSampledComputeWorkload(
override fun resolve(
loader: ComputeWorkloadLoader,
random: RandomGenerator,
- ): List<VirtualMachine> {
+ ): List<Task> {
val vms = source.resolve(loader, random)
val (hpc, nonHpc) =
@@ -65,7 +65,7 @@ internal class HpcSampledComputeWorkload(
val hpcSequence =
generateSequence(0) { it + 1 }
.map { index ->
- val res = mutableListOf<VirtualMachine>()
+ val res = mutableListOf<Task>()
hpc.mapTo(res) { sample(it, index) }
res
}
@@ -74,7 +74,7 @@ internal class HpcSampledComputeWorkload(
val nonHpcSequence =
generateSequence(0) { it + 1 }
.map { index ->
- val res = mutableListOf<VirtualMachine>()
+ val res = mutableListOf<Task>()
nonHpc.mapTo(res) { sample(it, index) }
res
}
@@ -90,7 +90,7 @@ internal class HpcSampledComputeWorkload(
var nonHpcCount = 0
var nonHpcLoad = 0.0
- val res = mutableListOf<VirtualMachine>()
+ val res = mutableListOf<Task>()
if (sampleLoad) {
var currentLoad = 0.0
@@ -146,9 +146,9 @@ internal class HpcSampledComputeWorkload(
* Sample a random trace entry.
*/
private fun sample(
- entry: VirtualMachine,
+ entry: Task,
i: Int,
- ): VirtualMachine {
+ ): Task {
val uid = UUID.nameUUIDFromBytes("${entry.uid}-$i".toByteArray())
return entry.copy(uid = uid)
}
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt
index 51ddb27c..534ac6a0 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt
+++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/LoadSampledComputeWorkload.kt
@@ -25,7 +25,7 @@ package org.opendc.compute.workload.internal
import mu.KotlinLogging
import org.opendc.compute.workload.ComputeWorkload
import org.opendc.compute.workload.ComputeWorkloadLoader
-import org.opendc.compute.workload.VirtualMachine
+import org.opendc.compute.workload.Task
import java.util.random.RandomGenerator
/**
@@ -40,9 +40,9 @@ internal class LoadSampledComputeWorkload(val source: ComputeWorkload, val fract
override fun resolve(
loader: ComputeWorkloadLoader,
random: RandomGenerator,
- ): List<VirtualMachine> {
+ ): List<Task> {
val vms = source.resolve(loader, random) // fixme: Should be shuffled, otherwise the first fraction is always chosen
- val res = mutableListOf<VirtualMachine>()
+ val res = mutableListOf<Task>()
val totalLoad = vms.sumOf { it.totalLoad }
var currentLoad = 0.0
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt
index 39255c59..d796341b 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt
+++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/internal/TraceComputeWorkload.kt
@@ -24,7 +24,7 @@ package org.opendc.compute.workload.internal
import org.opendc.compute.workload.ComputeWorkload
import org.opendc.compute.workload.ComputeWorkloadLoader
-import org.opendc.compute.workload.VirtualMachine
+import org.opendc.compute.workload.Task
import java.util.random.RandomGenerator
/**
@@ -34,7 +34,7 @@ internal class TraceComputeWorkload(val name: String, val format: String) : Comp
override fun resolve(
loader: ComputeWorkloadLoader,
random: RandomGenerator,
- ): List<VirtualMachine> {
+ ): List<Task> {
return loader.get(name, format)
}
}