Skip to content

Commit 5e4a08f

Browse files
authored
feat: adding instantiate action (#130)
1 parent 68cdb8d commit 5e4a08f

45 files changed

Lines changed: 933 additions & 718 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/main/kotlin/at/ac/uibk/dps/cirrina/Cirrina.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ private val logger = KotlinLogging.logger {}
99

1010
class Cirrina {
1111
fun run() {
12-
1312
val component = DaggerCirrinaComponent.create()
1413

1514
logger.info { "cirrina version ${getBuildVersion()}" }

src/main/kotlin/at/ac/uibk/dps/cirrina/Runtime.kt

Lines changed: 78 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,24 @@ package at.ac.uibk.dps.cirrina
22

33
import at.ac.uibk.dps.cirrina.cirrina.di.Main
44
import at.ac.uibk.dps.cirrina.cirrina.di.Run
5-
import at.ac.uibk.dps.cirrina.execution.graph.EventGraph
65
import at.ac.uibk.dps.cirrina.execution.`object`.*
76
import at.ac.uibk.dps.cirrina.execution.service.RandomServiceImplementationSelector
87
import at.ac.uibk.dps.cirrina.execution.service.ServiceImplementation
9-
import at.ac.uibk.dps.cirrina.execution.service.ServiceImplementationSelector
108
import at.ac.uibk.dps.cirrina.io.CsmParser
9+
import at.ac.uibk.dps.cirrina.spec.ContextVariable
1110
import at.ac.uibk.dps.cirrina.spec.Csml as CsmlSpec
11+
import at.ac.uibk.dps.cirrina.spec.Event
12+
import at.ac.uibk.dps.cirrina.spec.Instance
13+
import at.ac.uibk.dps.cirrina.spec.graph.EventGraph
1214
import com.codahale.metrics.MetricRegistry
1315
import com.codahale.metrics.Timer
1416
import jakarta.inject.Inject
1517
import java.net.URI
18+
import kotlin.collections.component1
19+
import kotlin.collections.component2
1620
import kotlin.time.measureTime
1721
import kotlin.time.toJavaDuration
22+
import kotlinx.coroutines.SupervisorJob
1823
import kotlinx.coroutines.joinAll
1924
import kotlinx.coroutines.runBlocking
2025
import mu.KotlinLogging
@@ -24,75 +29,100 @@ private val logger = KotlinLogging.logger {}
2429
class Runtime
2530
@Inject
2631
constructor(
27-
@Run private val run: List<String>,
32+
@Run run: List<String>,
2833
@Main main: URI,
34+
metricRegistry: MetricRegistry,
2935
persistentContext: Context?,
3036
stateMachineFactory: StateMachine.Factory,
31-
val metricRegistry: MetricRegistry,
32-
) {
33-
val eventHandler = EventHandler()
37+
) : PropagationHandler {
3438
val extent = persistentContext?.let { Extent.of(it) } ?: Extent.of()
3539

36-
val selector: ServiceImplementationSelector
40+
val eventHandler = EventHandler(this)
3741

38-
private val instances: Map<String, StateMachine>
42+
private val csml =
43+
CsmlSpec.create(CsmParser.parseCsml(main))
44+
.onFailure { logger.error(it) { "failed to initialize collaborative state machine class" } }
45+
.getOrThrow()
3946

40-
private val graph: EventGraph
47+
val serviceImplementationSelector =
48+
RandomServiceImplementationSelector(ServiceImplementation.from(csml.bindings ?: emptyList()))
49+
50+
private val runtimeJob = SupervisorJob()
4151

4252
private var completion: Timer = metricRegistry.timer("runtime.completionTime")
4353

44-
init {
45-
val spec =
46-
CsmlSpec.create(CsmParser.parseCsml(main))
47-
.onFailure { logger.error(it) { "failed to initialize collaborative state machine class" } }
48-
.getOrThrow()
54+
inner class InstanceRegistry(private val stateMachineFactory: StateMachine.Factory) {
55+
@Volatile
56+
var version = 0L
57+
private set
4958

50-
selector =
51-
RandomServiceImplementationSelector(ServiceImplementation.from(spec.bindings ?: emptyList()))
59+
private val graph = EventGraph()
5260

53-
persistentContext?.let { context ->
54-
spec.collaborativeStateMachine.persistentContext.forEach { variable ->
55-
runCatching { context.create(variable.name, variable.value) }
56-
.onFailure {
57-
logger.warn { "variable '${variable.name}' already exists or failed to create" }
58-
}
59-
}
61+
val instances: List<StateMachine>
62+
get() = graph.instances
63+
64+
fun instantiate(
65+
instance: Instance,
66+
instanceData: List<ContextVariable> =
67+
instance.data.map { (k, v) -> ContextVariable(k, v.evaluate()) },
68+
) {
69+
val hierarchy =
70+
stateMachineFactory.createHierarchy(
71+
name = instance.name,
72+
specification = instance.stateMachine,
73+
instanceData = instanceData,
74+
instanceSubscription = instance.subscription,
75+
instanceRegistry = this,
76+
parent = null,
77+
runtimeExtent = extent,
78+
eventHandler = eventHandler,
79+
serviceImplementationSelector = serviceImplementationSelector,
80+
)
81+
82+
hierarchy.forEach { machine -> graph.addInstance(machine) }
83+
84+
++version
85+
86+
val instances = graph.instances
87+
88+
eventHandler.addPublishers(graph.getOutgoing(instances).map { it.event })
89+
eventHandler.addSubscribers(instances.flatMap { it.subscriptions })
90+
91+
hierarchy.forEach { machine -> machine.start(parentContext = runtimeJob) }
6092
}
6193

62-
instances =
63-
spec.instances
64-
.filter { it.name in run }
65-
.flatMap { instance ->
66-
stateMachineFactory.createHierarchy(
67-
name = instance.name,
68-
specification = instance.stateMachine,
69-
instance = instance,
70-
subscriptions =
71-
spec.instances.filter { instance.subscription.matches(it.name) }.map { it.name },
72-
runtime = this,
73-
parent = null,
74-
)
75-
}
76-
.associateBy { it.name }
94+
fun findStateMachineInstance(name: String): StateMachine? =
95+
graph.instances.filter { it.name == name }.firstOrNull()
96+
}
7797

78-
graph = EventGraph.create(spec.instances)
98+
private val instanceRegistry = InstanceRegistry(stateMachineFactory)
7999

80-
eventHandler.bind(
81-
graph = graph,
82-
instanceNames = run,
83-
subscribedTo = instances.values.flatMap { it.subscriptions }.toSet(),
84-
handlers = instances.values.map { it::pushEvent },
85-
)
100+
init {
101+
persistentContext?.let { context ->
102+
csml.collaborativeStateMachine.persistentContext.forEach { (k, v) ->
103+
runCatching { context.create(k, v.evaluate()) }
104+
.onFailure { logger.warn { "variable '${k}' already exists or failed to create" } }
105+
}
106+
}
107+
csml.instances.filter { it.name in run }.forEach { instanceRegistry.instantiate(it) }
86108
}
87109

88110
fun run() = runBlocking {
89-
measureTime { instances.values.map { it.start() }.joinAll() }
111+
measureTime {
112+
while (runtimeJob.children.any()) {
113+
runtimeJob.children.toList().joinAll()
114+
}
115+
116+
runtimeJob.complete()
117+
runtimeJob.join()
118+
}
90119
.also {
91120
completion.update(it.toJavaDuration())
92121
logger.info { "runtime terminated in $it" }
93122
}
94123
}
95124

96-
fun findStateMachineInstance(stateMachineObjectName: String): StateMachine? =
97-
instances[stateMachineObjectName]
125+
override fun invoke(event: Event) {
126+
instanceRegistry.instances.forEach { it.pushEvent(event) }
127+
}
98128
}

src/main/kotlin/at/ac/uibk/dps/cirrina/di/CirrinaModule.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import java.util.concurrent.TimeUnit
3131

3232
@Module
3333
class CirrinaModule {
34-
3534
@Provides
3635
@Singleton
3736
fun providePersistentContext(): Context? =

src/main/kotlin/at/ac/uibk/dps/cirrina/execution/graph/EventGraph.kt

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/main/kotlin/at/ac/uibk/dps/cirrina/execution/object/Action.kt

Lines changed: 0 additions & 124 deletions
This file was deleted.

0 commit comments

Comments
 (0)