summaryrefslogtreecommitdiff
path: root/opendc-compute/opendc-compute-service
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-compute/opendc-compute-service')
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt11
-rw-r--r--opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt64
-rw-r--r--opendc-compute/opendc-compute-service/src/test/kotlin/org/opendc/compute/service/ComputeServiceTest.kt4
3 files changed, 33 insertions, 46 deletions
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt
index fad8757e..efcc0f2c 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/driver/Host.kt
@@ -70,11 +70,8 @@ public interface Host {
/**
* Register the specified [instance][server] on the host.
- *
- * Once the method returns, the instance should be running if [start] is true or else the instance should be
- * stopped.
*/
- public suspend fun spawn(server: Server, start: Boolean = true)
+ public fun spawn(server: Server)
/**
* Determine whether the specified [instance][server] exists on the host.
@@ -86,19 +83,19 @@ public interface Host {
*
* @throws IllegalArgumentException if the server is not present on the host.
*/
- public suspend fun start(server: Server)
+ public fun start(server: Server)
/**
* Stop the server [instance][server] if it is currently running on this host.
*
* @throws IllegalArgumentException if the server is not present on the host.
*/
- public suspend fun stop(server: Server)
+ public fun stop(server: Server)
/**
* Delete the specified [instance][server] on this host and cleanup all resources associated with it.
*/
- public suspend fun delete(server: Server)
+ public fun delete(server: Server)
/**
* Add a [HostListener] to this host.
diff --git a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt
index 0fe016aa..b377c3e3 100644
--- a/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt
+++ b/opendc-compute/opendc-compute-service/src/main/kotlin/org/opendc/compute/service/internal/ComputeServiceImpl.kt
@@ -22,11 +22,6 @@
package org.opendc.compute.service.internal
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.isActive
-import kotlinx.coroutines.launch
import mu.KotlinLogging
import org.opendc.common.util.Pacer
import org.opendc.compute.api.ComputeClient
@@ -53,23 +48,18 @@ import kotlin.math.max
/**
* Internal implementation of the OpenDC Compute service.
*
- * @param context The [CoroutineContext] to use in the service.
+ * @param coroutineContext The [CoroutineContext] to use in the service.
* @param clock The clock instance to use.
* @param scheduler The scheduler implementation to use.
* @param schedulingQuantum The interval between scheduling cycles.
*/
internal class ComputeServiceImpl(
- private val context: CoroutineContext,
+ coroutineContext: CoroutineContext,
private val clock: Clock,
private val scheduler: ComputeScheduler,
schedulingQuantum: Duration
) : ComputeService, HostListener {
/**
- * The [CoroutineScope] of the service bounded by the lifecycle of the service.
- */
- private val scope = CoroutineScope(context + Job())
-
- /**
* The logger instance of this server.
*/
private val logger = KotlinLogging.logger {}
@@ -115,6 +105,9 @@ internal class ComputeServiceImpl(
private val serverById = mutableMapOf<UUID, InternalServer>()
override val servers: MutableList<Server> = mutableListOf()
+ override val hosts: Set<Host>
+ get() = hostToView.keys
+
private var maxCores = 0
private var maxMemory = 0L
private var _attemptsSuccess = 0L
@@ -122,17 +115,15 @@ internal class ComputeServiceImpl(
private var _attemptsError = 0L
private var _serversPending = 0
private var _serversActive = 0
+ private var isClosed = false
/**
* The [Pacer] to use for scheduling the scheduler cycles.
*/
- private val pacer = Pacer(scope.coroutineContext, clock, schedulingQuantum.toMillis()) { doSchedule() }
-
- override val hosts: Set<Host>
- get() = hostToView.keys
+ private val pacer = Pacer(coroutineContext, clock, schedulingQuantum.toMillis()) { doSchedule() }
override fun newClient(): ComputeClient {
- check(scope.isActive) { "Service is already closed" }
+ check(!isClosed) { "Service is already closed" }
return object : ComputeClient {
private var isClosed: Boolean = false
@@ -285,7 +276,12 @@ internal class ComputeServiceImpl(
}
override fun close() {
- scope.cancel()
+ if (isClosed) {
+ return
+ }
+
+ isClosed = true
+ pacer.cancel()
}
override fun getSchedulerStats(): SchedulerStats {
@@ -379,29 +375,23 @@ internal class ComputeServiceImpl(
logger.info { "Assigned server $server to host $host." }
- // Speculatively update the hypervisor view information to prevent other images in the queue from
- // deciding on stale values.
- hv.instanceCount++
- hv.provisionedCores += server.flavor.cpuCount
- hv.availableMemory -= server.flavor.memorySize // XXX Temporary hack
+ try {
+ server.host = host
- scope.launch {
- try {
- server.host = host
- host.spawn(server)
- activeServers[server] = host
+ host.spawn(server)
+ host.start(server)
- _serversActive++
- _attemptsSuccess++
- } catch (e: Throwable) {
- logger.error(e) { "Failed to deploy VM" }
+ _serversActive++
+ _attemptsSuccess++
- hv.instanceCount--
- hv.provisionedCores -= server.flavor.cpuCount
- hv.availableMemory += server.flavor.memorySize
+ hv.instanceCount++
+ hv.provisionedCores += server.flavor.cpuCount
+ hv.availableMemory -= server.flavor.memorySize
- _attemptsError++
- }
+ activeServers[server] = host
+ } catch (e: Throwable) {
+ logger.error(e) { "Failed to deploy VM" }
+ _attemptsError++
}
}
}
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
index 73e9b3d7..c18709f3 100644
--- 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
@@ -348,7 +348,7 @@ internal class ComputeServiceTest {
// Start server
server.start()
delay(5L * 60 * 1000)
- coVerify { host.spawn(capture(slot), true) }
+ coVerify { host.spawn(capture(slot)) }
listeners.forEach { it.onStateChanged(host, slot.captured, ServerState.RUNNING) }
@@ -376,7 +376,7 @@ internal class ComputeServiceTest {
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(), true) } throws IllegalStateException()
+ coEvery { host.spawn(any()) } throws IllegalStateException()
service.addHost(host)