All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.it.unibo.pulvreakt.runtime.component.SimpleComponentManager.kt Maven / Gradle / Ivy

There is a newer version: 0.10.0
Show newest version
package it.unibo.pulvreakt.runtime.component

import arrow.core.Either
import arrow.core.raise.either
import arrow.core.raise.ensureNotNull
import arrow.core.right
import io.github.oshai.kotlinlogging.KotlinLogging
import it.unibo.pulvreakt.api.component.Component
import it.unibo.pulvreakt.api.component.ComponentRef
import it.unibo.pulvreakt.errors.component.ComponentError
import it.unibo.pulvreakt.runtime.component.errors.ComponentManagerError
import it.unibo.pulvreakt.runtime.component.errors.ComponentNotRegistered
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.coroutineScope

internal class SimpleComponentManager : ComponentManager {
    private var componentContainer = emptyMap>?>()
    private val logger = KotlinLogging.logger("SimpleComponentManager")

    override fun register(component: Component) {
        logger.debug { "Registered component: $component" }
        componentContainer += component to null
    }

    override suspend fun start(component: ComponentRef): Either>> = coroutineScope {
        either {
            logger.debug { "components: $componentContainer - $component" }
            val candidateComponent = componentContainer.keys.firstOrNull { it.getRef() == component }
            ensureNotNull(candidateComponent) { ComponentNotRegistered(component) }
            logger.debug { "Starting the execution of $component" }
            val jobRef = async { candidateComponent.execute() }
            componentContainer += candidateComponent to jobRef
            jobRef
        }
    }

    override suspend fun stop(component: ComponentRef): Either = either {
        val candidateComponent = componentContainer.keys.firstOrNull { it.getRef() == component }
        ensureNotNull(candidateComponent) { ComponentNotRegistered(component) }
        logger.debug { "Stop the execution of ${component::class.simpleName}" }
        componentContainer[candidateComponent]
            ?.cancelAndJoin()
            ?: run {
                logger.warn { "Tried to cancel a non-running component" }
                logger.debug { "Tried to cancel the ${component::class.simpleName} but it was not running" }
            }
        componentContainer += candidateComponent to null
    }

    override suspend fun stopAll(): Either =
        componentContainer.keys.map { it.getRef() }.forEach { stop(it) }.right()

    override fun alive(): Set = componentContainer
        .filterValues { it != null }
        .keys.map { it.getRef() }
        .toSet()

    override suspend fun initialize(): Either = Unit.right()
    override suspend fun finalize(): Either = Unit.right()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy