diff options
| author | Dante Niewenhuis <d.niewenhuis@hotmail.com> | 2024-10-25 13:32:41 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-25 13:32:41 +0200 |
| commit | 5a365dbc068f2a8cdfa9813c39cc84bb30e15637 (patch) | |
| tree | 72716d562787b85e03cdc7fe1d30c827054d25a0 /opendc-faas/opendc-faas-service | |
| parent | 27f5b7dcb05aefdab9b762175d538931face0aba (diff) | |
Rewrote the FlowEngine (#256)
* Removed unused components. Updated tests.
Improved checkpointing model
Improved model, started with SimPowerSource
implemented FailureModels and Checkpointing
First working version
midway commit
first update
All simulation are now run with a single CPU and single MemoryUnit. multi CPUs are combined into one. This is for performance and explainability.
* fixed merge conflicts
* Updated M3SA paths.
* Fixed small typo
Diffstat (limited to 'opendc-faas/opendc-faas-service')
17 files changed, 0 insertions, 1295 deletions
diff --git a/opendc-faas/opendc-faas-service/build.gradle.kts b/opendc-faas/opendc-faas-service/build.gradle.kts deleted file mode 100644 index 90cb8f56..00000000 --- a/opendc-faas/opendc-faas-service/build.gradle.kts +++ /dev/null @@ -1,39 +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 = "FaaS service for OpenDC" - -// Build configuration -plugins { - `kotlin-library-conventions` -} - -dependencies { - api(projects.opendcFaas.opendcFaasApi) - api(libs.commons.math3) - implementation(projects.opendcCommon) - implementation(libs.kotlin.logging) - - testImplementation(projects.opendcSimulator.opendcSimulatorCore) - testRuntimeOnly(libs.log4j.core) - testRuntimeOnly(libs.log4j.slf4j) -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FaaSService.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FaaSService.kt deleted file mode 100644 index e9634ccc..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FaaSService.kt +++ /dev/null @@ -1,80 +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.faas.service - -import org.opendc.common.Dispatcher -import org.opendc.faas.api.FaaSClient -import org.opendc.faas.api.FaaSFunction -import org.opendc.faas.service.autoscaler.FunctionTerminationPolicy -import org.opendc.faas.service.deployer.FunctionDeployer -import org.opendc.faas.service.internal.FaaSServiceImpl -import org.opendc.faas.service.router.RoutingPolicy -import org.opendc.faas.service.telemetry.FunctionStats -import org.opendc.faas.service.telemetry.SchedulerStats -import java.time.Duration - -/** - * The [FaaSService] hosts the service implementation of the OpenDC FaaS platform. - */ -public interface FaaSService : AutoCloseable { - /** - * Create a new [FaaSClient] to control the compute service. - */ - public fun newClient(): FaaSClient - - /** - * Collect statistics about the scheduler of the service. - */ - public fun getSchedulerStats(): SchedulerStats - - /** - * Collect statistics about the specified [function]. - */ - public fun getFunctionStats(function: FaaSFunction): FunctionStats - - /** - * Terminate the lifecycle of the FaaS service, stopping all running function instances. - */ - public override fun close() - - public companion object { - /** - * Construct a new [FaaSService] implementation. - * - * @param dispatcher The [Dispatcher] used for scheduling events. - * @param deployer the [FunctionDeployer] to use for deploying function instances. - * @param routingPolicy The policy to route function invocations. - * @param terminationPolicy The policy for terminating function instances. - * @param quantum The scheduling quantum of the service (100 ms default) - */ - public operator fun invoke( - dispatcher: Dispatcher, - deployer: FunctionDeployer, - routingPolicy: RoutingPolicy, - terminationPolicy: FunctionTerminationPolicy, - quantum: Duration = Duration.ofMillis(100), - ): FaaSService { - return FaaSServiceImpl(dispatcher, deployer, routingPolicy, terminationPolicy, quantum) - } - } -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt deleted file mode 100644 index 0ed96b96..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/FunctionObject.kt +++ /dev/null @@ -1,145 +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.faas.service - -import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics -import org.opendc.faas.service.deployer.FunctionInstance -import org.opendc.faas.service.telemetry.FunctionStats -import java.util.UUID - -/** - * An [FunctionObject] represents the service's view of a serverless function. - */ -public class FunctionObject( - public val uid: UUID, - name: String, - allocatedMemory: Long, - labels: Map<String, String>, - meta: Map<String, Any>, -) : AutoCloseable { - /** - * Metrics tracked per function. - */ - private var localInvocations = 0L - private var localTimelyInvocations = 0L - private var localDelayedInvocations = 0L - private var localFailedInvocations = 0L - private var localActiveInstances = 0 - private var localIdleInstances = 0 - private val localWaitTime = - DescriptiveStatistics() - .apply { windowSize = 100 } - private val localActiveTime = - DescriptiveStatistics() - .apply { windowSize = 100 } - - /** - * The instances associated with this function. - */ - public val instances: MutableList<FunctionInstance> = mutableListOf() - - public var name: String = name - private set - - public var memorySize: Long = allocatedMemory - private set - - public val labels: MutableMap<String, String> = labels.toMutableMap() - - public val meta: MutableMap<String, Any> = meta.toMutableMap() - - /** - * Report a scheduled invocation. - */ - internal fun reportSubmission() { - localInvocations++ - } - - /** - * Report the deployment of an invocation. - */ - internal fun reportDeployment(isDelayed: Boolean) { - if (isDelayed) { - localDelayedInvocations++ - localIdleInstances++ - } else { - localTimelyInvocations++ - } - } - - /** - * Report the start of a function invocation. - */ - internal fun reportStart( - start: Long, - submitTime: Long, - ) { - val wait = start - submitTime - localWaitTime.addValue(wait.toDouble()) - - localIdleInstances-- - localActiveInstances++ - } - - /** - * Report the failure of a function invocation. - */ - internal fun reportFailure() { - localFailedInvocations++ - } - - /** - * Report the end of a function invocation. - */ - internal fun reportEnd(duration: Long) { - localActiveTime.addValue(duration.toDouble()) - localIdleInstances++ - localActiveInstances-- - } - - /** - * Collect the statistics of this function. - */ - internal fun getStats(): FunctionStats { - return FunctionStats( - localInvocations, - localTimelyInvocations, - localDelayedInvocations, - localFailedInvocations, - localActiveInstances, - localIdleInstances, - localWaitTime.copy(), - localActiveTime.copy(), - ) - } - - override fun close() { - val copy = instances.toList() // Make copy to prevent concurrent modification - copy.forEach(FunctionInstance::close) - instances.clear() - } - - override fun equals(other: Any?): Boolean = other is FunctionObject && uid == other.uid - - override fun hashCode(): Int = uid.hashCode() -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicy.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicy.kt deleted file mode 100644 index 2ab3638b..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicy.kt +++ /dev/null @@ -1,36 +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.faas.service.autoscaler - -import org.opendc.faas.service.deployer.FunctionInstance -import org.opendc.faas.service.deployer.FunctionInstanceListener - -/** - * A management policy that is responsible for downscaling the active function instances for a function. - */ -public interface FunctionTerminationPolicy : FunctionInstanceListener { - /** - * Enqueue the specified [instance] to be scheduled for termination a - */ - public fun enqueue(instance: FunctionInstance) -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicyFixed.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicyFixed.kt deleted file mode 100644 index 9edb8c1d..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicyFixed.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.faas.service.autoscaler - -import org.opendc.common.Dispatcher -import org.opendc.common.util.TimerScheduler -import org.opendc.faas.service.deployer.FunctionInstance -import org.opendc.faas.service.deployer.FunctionInstanceState -import java.time.Duration - -/** - * A [FunctionTerminationPolicy] that terminates idle function instances after a fixed keep-alive time. - * - * @param timeout The idle timeout after which the function instance is terminated. - */ -public class FunctionTerminationPolicyFixed( - dispatcher: Dispatcher, - public val timeout: Duration, -) : FunctionTerminationPolicy { - /** - * The [TimerScheduler] used to schedule the function terminations. - */ - private val scheduler = TimerScheduler<FunctionInstance>(dispatcher) - - override fun enqueue(instance: FunctionInstance) { - // Cancel the existing timeout timer - scheduler.cancel(instance) - } - - override fun onStateChanged( - instance: FunctionInstance, - newState: FunctionInstanceState, - ) { - when (newState) { - FunctionInstanceState.Active -> scheduler.cancel(instance) - FunctionInstanceState.Idle -> schedule(instance) - else -> {} - } - } - - /** - * Schedule termination for the specified [instance]. - */ - private fun schedule(instance: FunctionInstance) { - scheduler.startSingleTimer(instance, timeout.toMillis()) { instance.close() } - } -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicyNull.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicyNull.kt deleted file mode 100644 index 957e569b..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/autoscaler/FunctionTerminationPolicyNull.kt +++ /dev/null @@ -1,34 +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.faas.service.autoscaler - -import org.opendc.faas.service.deployer.FunctionInstance - -/** - * A [FunctionTerminationPolicy] that never terminates function instances. - */ -public class FunctionTerminationPolicyNull : FunctionTerminationPolicy { - override fun enqueue(instance: FunctionInstance) { - // No-op - } -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionDeployer.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionDeployer.kt deleted file mode 100644 index 13d48fbf..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionDeployer.kt +++ /dev/null @@ -1,46 +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.faas.service.deployer - -import org.opendc.faas.service.FunctionObject - -/** - * A [FunctionDeployer] is responsible for ensuring that an instance of an arbitrary function, a [FunctionInstance], - * is deployed. - * - * The function deployer should combine the configuration stored in the function registry, the parameters supplied by - * the requester, and other factors into a decision of how the function should be deployed, including how many and - * what kind of resources it should receive. - * - * Though it decides how the function instance should be deployed, the deployment of the function instance itself is - * delegated to the Resource Orchestration Layer. - */ -public interface FunctionDeployer { - /** - * Deploy the specified [function]. - */ - public fun deploy( - function: FunctionObject, - listener: FunctionInstanceListener, - ): FunctionInstance -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionInstance.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionInstance.kt deleted file mode 100644 index 77eadbbe..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionInstance.kt +++ /dev/null @@ -1,55 +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.faas.service.deployer - -import org.opendc.faas.service.FunctionObject - -/** - * A [FunctionInstance] is a self-contained worker—typically a container—capable of handling function executions. - * - * Multiple, concurrent function instances can exist for a single function, for scalability purposes. - */ -public interface FunctionInstance : AutoCloseable { - /** - * The state of the instance. - */ - public val state: FunctionInstanceState - - /** - * The [FunctionObject] that is represented by this instance. - */ - public val function: FunctionObject - - /** - * Invoke the function instance. - * - * This method will suspend execution util the function instance has returned. - */ - public suspend fun invoke() - - /** - * Indicate to the resource manager that the instance is not needed anymore and may be cleaned up by the resource - * manager. - */ - public override fun close() -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionInstanceListener.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionInstanceListener.kt deleted file mode 100644 index e88b7104..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionInstanceListener.kt +++ /dev/null @@ -1,36 +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.faas.service.deployer - -/** - * Listener interface for events originating from a [FunctionInstance]. - */ -public interface FunctionInstanceListener { - /** - * This method is invoked when the state of a [FunctionInstance] has changed. - */ - public fun onStateChanged( - instance: FunctionInstance, - newState: FunctionInstanceState, - ) {} -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionInstanceState.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionInstanceState.kt deleted file mode 100644 index 0c310e6b..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/deployer/FunctionInstanceState.kt +++ /dev/null @@ -1,48 +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.faas.service.deployer - -/** - * This enumeration describes the states of a [FunctionInstance]. - */ -public enum class FunctionInstanceState { - /** - * The function instance is currently being provisioned. - */ - Provisioning, - - /** - * The function instance is idle and ready to execute. - */ - Idle, - - /** - * The function instance is executing. - */ - Active, - - /** - * The function instance is released and cannot be used anymore. - */ - Deleted, -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSFunctionImpl.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSFunctionImpl.kt deleted file mode 100644 index 7cc85e40..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSFunctionImpl.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.faas.service.internal - -import org.opendc.faas.api.FaaSFunction -import org.opendc.faas.service.FunctionObject -import java.util.UUID - -/** - * A [FaaSFunction] implementation that is passed to clients. - */ -internal class FaaSFunctionImpl( - private val service: FaaSServiceImpl, - private val state: FunctionObject, -) : FaaSFunction { - override val uid: UUID = state.uid - - override var name: String = state.name - private set - - override var memorySize: Long = state.memorySize - private set - - override var labels: Map<String, String> = state.labels.toMap() - private set - - override var meta: Map<String, Any> = state.meta.toMap() - private set - - override suspend fun delete() { - service.delete(state) - } - - override suspend fun invoke() { - service.invoke(state) - } - - override suspend fun refresh() { - name = state.name - memorySize = state.memorySize - labels = state.labels - meta = state.meta - } - - override fun equals(other: Any?): Boolean = other is FaaSFunctionImpl && uid == other.uid - - override fun hashCode(): Int = uid.hashCode() - - override fun toString(): String = "FaaSFunction[uid=$uid,name=$name]" -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt deleted file mode 100644 index 397b0e7d..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/internal/FaaSServiceImpl.kt +++ /dev/null @@ -1,290 +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.faas.service.internal - -import kotlinx.coroutines.InternalCoroutinesApi -import kotlinx.coroutines.intrinsics.startCoroutineCancellable -import kotlinx.coroutines.suspendCancellableCoroutine -import mu.KotlinLogging -import org.opendc.common.Dispatcher -import org.opendc.common.util.Pacer -import org.opendc.faas.api.FaaSClient -import org.opendc.faas.api.FaaSFunction -import org.opendc.faas.service.FaaSService -import org.opendc.faas.service.FunctionObject -import org.opendc.faas.service.autoscaler.FunctionTerminationPolicy -import org.opendc.faas.service.deployer.FunctionDeployer -import org.opendc.faas.service.deployer.FunctionInstance -import org.opendc.faas.service.deployer.FunctionInstanceListener -import org.opendc.faas.service.deployer.FunctionInstanceState -import org.opendc.faas.service.router.RoutingPolicy -import org.opendc.faas.service.telemetry.FunctionStats -import org.opendc.faas.service.telemetry.SchedulerStats -import java.lang.IllegalStateException -import java.time.Duration -import java.time.InstantSource -import java.util.ArrayDeque -import java.util.Random -import java.util.UUID -import kotlin.coroutines.Continuation -import kotlin.coroutines.resumeWithException - -/** - * Implementation of the [FaaSService] interface. - * - * This component acts as the function router from the SPEC RG Reference Architecture for FaaS and is responsible - * for routing incoming requests or events to the correct [FunctionInstance]. If no [FunctionInstance] is available, - * this component queues the events to await the deployment of new instances. - */ -internal class FaaSServiceImpl( - dispatcher: Dispatcher, - private val deployer: FunctionDeployer, - private val routingPolicy: RoutingPolicy, - private val terminationPolicy: FunctionTerminationPolicy, - quantum: Duration, -) : FaaSService, FunctionInstanceListener { - /** - * The logger instance of this server. - */ - private val logger = KotlinLogging.logger {} - - /** - * The [Pacer] to use for scheduling the scheduler cycles. - */ - private val pacer = Pacer(dispatcher, quantum.toMillis()) { doSchedule() } - - /** - * The [InstantSource] instance representing the clock. - */ - private val clock = dispatcher.timeSource - - /** - * The [Random] instance used to generate unique identifiers for the objects. - */ - private val random = Random(0) - - /** - * The registered functions for this service. - */ - private val functions = mutableMapOf<UUID, FunctionObject>() - private val functionsByName = mutableMapOf<String, FunctionObject>() - - /** - * The queue of invocation requests. - */ - private val queue = ArrayDeque<InvocationRequest>() - - /** - * Metrics tracked by the service. - */ - private var totalInvocations = 0L - private var timelyInvocations = 0L - private var delayedInvocations = 0L - - override fun newClient(): FaaSClient { - return object : FaaSClient { - private var isClosed: Boolean = false - - /** - * Exposes a [FunctionObject] to a client-exposed [FaaSFunction] instance. - */ - private fun FunctionObject.asClientFunction(): FaaSFunction { - return FaaSFunctionImpl(this@FaaSServiceImpl, this) - } - - override suspend fun queryFunctions(): List<FaaSFunction> { - check(!isClosed) { "Client is already closed" } - - return functions.values.map { it.asClientFunction() } - } - - override suspend fun findFunction(id: UUID): FaaSFunction? { - check(!isClosed) { "Client is already closed" } - - return functions[id]?.asClientFunction() - } - - override suspend fun findFunction(name: String): FaaSFunction? { - check(!isClosed) { "Client is already closed" } - - return functionsByName[name]?.asClientFunction() - } - - override suspend fun newFunction( - name: String, - memorySize: Long, - labels: Map<String, String>, - meta: Map<String, Any>, - ): FaaSFunction { - check(!isClosed) { "Client is already closed" } - require(name !in functionsByName) { "Function with same name exists" } - - val uid = UUID(clock.millis(), random.nextLong()) - val function = - FunctionObject( - uid, - name, - memorySize, - labels, - meta, - ) - - functionsByName[name] = function - functions[uid] = function - - return function.asClientFunction() - } - - override suspend fun invoke(name: String) { - check(!isClosed) { "Client is already closed" } - - val func = requireNotNull(functionsByName[name]) { "Unknown function" } - this@FaaSServiceImpl.invoke(func) - } - - override fun close() { - isClosed = true - } - } - } - - override fun getSchedulerStats(): SchedulerStats { - return SchedulerStats(totalInvocations, timelyInvocations, delayedInvocations) - } - - override fun getFunctionStats(function: FaaSFunction): FunctionStats { - val func = requireNotNull(functions[function.uid]) { "Unknown function" } - return func.getStats() - } - - /** - * Indicate that a new scheduling cycle is needed due to a change to the service's state. - */ - private fun schedule() { - // Bail out in case the queue is empty. - if (queue.isEmpty()) { - return - } - - pacer.enqueue() - } - - /** - * Run a single scheduling iteration. - */ - @OptIn(InternalCoroutinesApi::class) - private fun doSchedule() { - try { - while (queue.isNotEmpty()) { - val (submitTime, function, cont) = queue.poll() - - val instances = function.instances - - // Check if there exists an instance of the function - val activeInstance = - if (instances.isNotEmpty()) { - routingPolicy.select(instances, function) - } else { - null - } - - val instance = - if (activeInstance != null) { - timelyInvocations++ - function.reportDeployment(isDelayed = false) - - activeInstance - } else { - val instance = deployer.deploy(function, this) - instances.add(instance) - terminationPolicy.enqueue(instance) - - delayedInvocations++ - function.reportDeployment(isDelayed = true) - - instance - } - - suspend { - val start = clock.millis() - function.reportStart(start, submitTime) - try { - instance.invoke() - } catch (e: Throwable) { - logger.debug(e) { "Function invocation failed" } - function.reportFailure() - } finally { - val end = clock.millis() - function.reportEnd(end - start) - } - }.startCoroutineCancellable(cont) - } - } catch (cause: Throwable) { - logger.error(cause) { "Exception occurred during scheduling cycle" } - } - } - - suspend fun invoke(function: FunctionObject) { - check(function.uid in functions) { "Function does not exist (anymore)" } - - totalInvocations++ - function.reportSubmission() - - return suspendCancellableCoroutine { cont -> - if (!queue.add(InvocationRequest(clock.millis(), function, cont))) { - cont.resumeWithException(IllegalStateException("Failed to enqueue request")) - } else { - schedule() - } - } - } - - fun delete(function: FunctionObject) { - functions.remove(function.uid) - functionsByName.remove(function.name) - } - - override fun close() { - // Stop all function instances - for ((_, function) in functions) { - function.close() - } - } - - override fun onStateChanged( - instance: FunctionInstance, - newState: FunctionInstanceState, - ) { - terminationPolicy.onStateChanged(instance, newState) - - if (newState == FunctionInstanceState.Deleted) { - val function = instance.function - function.instances.remove(instance) - } - } - - /** - * A request to invoke a function. - */ - private data class InvocationRequest(val timestamp: Long, val function: FunctionObject, val cont: Continuation<Unit>) -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/router/RandomRoutingPolicy.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/router/RandomRoutingPolicy.kt deleted file mode 100644 index 1eb03e5a..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/router/RandomRoutingPolicy.kt +++ /dev/null @@ -1,41 +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.faas.service.router - -import org.opendc.faas.service.FunctionObject -import org.opendc.faas.service.deployer.FunctionInstance -import java.util.SplittableRandom -import java.util.random.RandomGenerator - -/** - * A [RoutingPolicy] that selects a random function instance. - */ -public class RandomRoutingPolicy(private val random: RandomGenerator = SplittableRandom(0)) : RoutingPolicy { - override fun select( - instances: List<FunctionInstance>, - function: FunctionObject, - ): FunctionInstance { - val idx = random.nextInt(instances.size) - return instances.elementAt(idx) - } -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/router/RoutingPolicy.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/router/RoutingPolicy.kt deleted file mode 100644 index c8ea37fc..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/router/RoutingPolicy.kt +++ /dev/null @@ -1,39 +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.faas.service.router - -import org.opendc.faas.service.FunctionObject -import org.opendc.faas.service.deployer.FunctionInstance - -/** - * A [RoutingPolicy] decides to which [FunctionInstance] a function invocation should be routed. - */ -public interface RoutingPolicy { - /** - * Select the instance to which the request should be routed to. - */ - public fun select( - instances: List<FunctionInstance>, - function: FunctionObject, - ): FunctionInstance? -} diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/telemetry/FunctionStats.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/telemetry/FunctionStats.kt deleted file mode 100644 index db6db6c1..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/telemetry/FunctionStats.kt +++ /dev/null @@ -1,48 +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.faas.service.telemetry - -import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics - -/** - * Statistics about function invocations. - * - * @property totalInvocations The number of function invocations. - * @property timelyInvocations The number of function invocations that could be handled directly. - * @property delayedInvocations The number of function invocations that are delayed (cold starts). - * @property failedInvocations The number of function invocations that failed. - * @property activeInstances The number of active function instances. - * @property idleInstances The number of idle function instances. - * @property waitTime Statistics about the wait time of a function invocation. - * @property activeTime Statistics about the runtime of a function invocation. - */ -public data class FunctionStats( - val totalInvocations: Long, - val timelyInvocations: Long, - val delayedInvocations: Long, - val failedInvocations: Long, - val activeInstances: Int, - val idleInstances: Int, - val waitTime: DescriptiveStatistics, - val activeTime: DescriptiveStatistics, -) diff --git a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/telemetry/SchedulerStats.kt b/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/telemetry/SchedulerStats.kt deleted file mode 100644 index b65dfb03..00000000 --- a/opendc-faas/opendc-faas-service/src/main/kotlin/org/opendc/faas/service/telemetry/SchedulerStats.kt +++ /dev/null @@ -1,36 +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.faas.service.telemetry - -/** - * Statistics reported by the FaaS scheduler. - * - * @property totalInvocations The total amount of function invocations received by the scheduler. - * @property timelyInvocations The amount of function invocations that could be handled directly. - * @property delayedInvocations The amount of function invocations that were delayed due to function deployment. - */ -public data class SchedulerStats( - val totalInvocations: Long, - val timelyInvocations: Long, - val delayedInvocations: Long, -) diff --git a/opendc-faas/opendc-faas-service/src/test/kotlin/org/opendc/faas/service/FaaSServiceTest.kt b/opendc-faas/opendc-faas-service/src/test/kotlin/org/opendc/faas/service/FaaSServiceTest.kt deleted file mode 100644 index 72a5f2c8..00000000 --- a/opendc-faas/opendc-faas-service/src/test/kotlin/org/opendc/faas/service/FaaSServiceTest.kt +++ /dev/null @@ -1,185 +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.faas.service - -import io.mockk.every -import io.mockk.mockk -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertNotNull -import org.junit.jupiter.api.Assertions.assertNull -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertDoesNotThrow -import org.junit.jupiter.api.assertThrows -import org.opendc.faas.api.FaaSFunction -import org.opendc.faas.service.deployer.FunctionDeployer -import org.opendc.faas.service.deployer.FunctionInstance -import org.opendc.faas.service.deployer.FunctionInstanceState -import org.opendc.simulator.kotlin.runSimulation -import java.util.UUID - -/** - * Test suite for the [FaaSService] implementation. - */ -internal class FaaSServiceTest { - @Test - fun testClientState() = - runSimulation { - val service = FaaSService(dispatcher, mockk(), mockk(), mockk()) - - val client = assertDoesNotThrow { service.newClient() } - assertDoesNotThrow { client.close() } - - assertThrows<IllegalStateException> { client.queryFunctions() } - assertThrows<IllegalStateException> { client.newFunction("test", 128) } - assertThrows<IllegalStateException> { client.invoke("test") } - assertThrows<IllegalStateException> { client.findFunction(UUID.randomUUID()) } - assertThrows<IllegalStateException> { client.findFunction("name") } - } - - @Test - fun testClientInvokeUnknown() = - runSimulation { - val service = FaaSService(dispatcher, mockk(), mockk(), mockk()) - - val client = service.newClient() - - assertThrows<IllegalArgumentException> { client.invoke("test") } - } - - @Test - fun testClientFunctionCreation() = - runSimulation { - val service = FaaSService(dispatcher, mockk(), mockk(), mockk()) - - val client = service.newClient() - - val function = client.newFunction("test", 128) - - assertEquals("test", function.name) - } - - @Test - fun testClientFunctionQuery() = - runSimulation { - val service = FaaSService(dispatcher, mockk(), mockk(), mockk()) - - val client = service.newClient() - - assertEquals(emptyList<FaaSFunction>(), client.queryFunctions()) - - val function = client.newFunction("test", 128) - - assertEquals(listOf(function), client.queryFunctions()) - } - - @Test - fun testClientFunctionFindById() = - runSimulation { - val service = FaaSService(dispatcher, mockk(), mockk(), mockk()) - - val client = service.newClient() - - assertEquals(emptyList<FaaSFunction>(), client.queryFunctions()) - - val function = client.newFunction("test", 128) - - assertNotNull(client.findFunction(function.uid)) - } - - @Test - fun testClientFunctionFindByName() = - runSimulation { - val service = FaaSService(dispatcher, mockk(), mockk(), mockk()) - - val client = service.newClient() - - assertEquals(emptyList<FaaSFunction>(), client.queryFunctions()) - - val function = client.newFunction("test", 128) - - assertNotNull(client.findFunction(function.name)) - } - - @Test - fun testClientFunctionDuplicateName() = - runSimulation { - val service = FaaSService(dispatcher, mockk(), mockk(), mockk()) - - val client = service.newClient() - - client.newFunction("test", 128) - - assertThrows<IllegalArgumentException> { client.newFunction("test", 128) } - } - - @Test - fun testClientFunctionDelete() = - runSimulation { - val service = FaaSService(dispatcher, mockk(), mockk(), mockk()) - - val client = service.newClient() - val function = client.newFunction("test", 128) - assertNotNull(client.findFunction(function.uid)) - function.delete() - assertNull(client.findFunction(function.uid)) - - // Delete should be idempotent - function.delete() - } - - @Test - fun testClientFunctionCannotInvokeDeleted() = - runSimulation { - val service = FaaSService(dispatcher, mockk(), mockk(), mockk()) - - val client = service.newClient() - val function = client.newFunction("test", 128) - assertNotNull(client.findFunction(function.uid)) - function.delete() - - assertThrows<IllegalStateException> { function.invoke() } - } - - @Test - fun testClientFunctionInvoke() = - runSimulation { - val deployer = mockk<FunctionDeployer>() - val service = FaaSService(dispatcher, deployer, mockk(), mockk(relaxUnitFun = true)) - - every { deployer.deploy(any(), any()) } answers { - object : FunctionInstance { - override val state: FunctionInstanceState = FunctionInstanceState.Idle - override val function: FunctionObject = it.invocation.args[0] as FunctionObject - - override suspend fun invoke() {} - - override fun close() {} - } - } - - val client = service.newClient() - val function = client.newFunction("test", 128) - - function.invoke() - } -} |
