Skip to content

Commit 0292a87

Browse files
author
Gregor Holzer
committed
feat: add service invocation output variables
1 parent 1a602fd commit 0292a87

5 files changed

Lines changed: 45 additions & 6 deletions

File tree

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ sealed interface Action {
1313
description.type,
1414
description.mode,
1515
buildVariables(description.input),
16+
description.output,
1617
buildEvents(description.emits),
1718
)
1819

@@ -67,12 +68,13 @@ internal constructor(
6768
val type: String,
6869
val mode: InvocationMode,
6970
val input: List<ContextVariable>,
71+
val output: List<ContextVariableReferenceDescription>,
7072
val emits: List<Event>,
7173
) : EventRaisingAction {
7274
override fun raises(): List<Event> = emits
7375

7476
override fun toString() =
75-
"InvokeAction(type='$type', mode='$mode', input='$input', emits='$emits')"
77+
"InvokeAction(type='$type', mode='$mode', input='$input', output='$output', emits='$emits')"
7678
}
7779

7880
class MatchAction

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ internal constructor(
8080

8181
commandExecutionContext.coroutineScope.launch {
8282
runCatching { service.invoke(input) }
83-
.onSuccess { emitEvents(it) }
83+
.onSuccess {
84+
assignServiceOutput(it, commandExecutionContext.scope.extent)
85+
emitEvents(it)
86+
}
8487
.onFailure { logger.error(it) { "service invocation failed" } }
8588
}
8689

@@ -108,6 +111,24 @@ internal constructor(
108111
handler(event)
109112
}
110113
}
114+
115+
private fun assignServiceOutput(output: List<ContextVariable>, extent: Extent) {
116+
invokeAction.output.forEach { variable ->
117+
output
118+
.firstOrNull { it.name == variable.reference }
119+
?.let {
120+
runCatching { extent.set(variable.reference, it.value) }
121+
.onFailure { e ->
122+
logger.warn(e) {
123+
"failed to assign service output to variable '${variable.reference}'"
124+
}
125+
}
126+
}
127+
?: logger.warn {
128+
"service output does not contain expected variable '${variable.reference}'"
129+
}
130+
}
131+
}
111132
}
112133

113134
class MatchActionCommand

src/main/resources/pkl/csm/csml.pkl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class InvokeDescription extends ActionDescription {
9696
type: InvocationType
9797
mode: InvocationMode = "remote"
9898
input: Context
99+
output: Listing<ContextVariableReferenceDescription>
99100
emits: Listing<EventDescription>
100101
}
101102

@@ -131,6 +132,10 @@ class LogDescription extends ActionDescription {
131132
message: Expression
132133
}
133134

135+
class ContextVariableReferenceDescription {
136+
reference: String
137+
}
138+
134139
typealias EventTopic = String(matches(Regex(#"^[a-zA-Z_]\w*$"#)))
135140

136141
typealias EventChannel = "internal"|"external"|"peripheral"

src/test/kotlin/at/ac/uibk/dps/cirrina/CompleteTest.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ class CompleteTest {
2727
val context = ContextInMemory()
2828
val server = mockHttpServer { input ->
2929
val v = input.firstOrNull { it.name == "v" } ?: error("variable 'v' not found")
30-
listOf(ContextVariable("v", (v.value as Int) + 1))
30+
listOf(
31+
ContextVariable("v", (v.value as Int) + 1),
32+
ContextVariable("s", (v.value + 1) * 10),
33+
)
3134
}
3235

3336
try {
@@ -43,6 +46,7 @@ class CompleteTest {
4346
assertEquals(100, context.get("v"))
4447
assertEquals(true, context.get("b"))
4548
assertEquals(true, context.get("e"))
49+
assertEquals(50500, context.get("f"))
4650
} finally {
4751
server.stop(1)
4852
}

src/test/resources/pkl/complete/main.pkl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ collaborativeStateMachine {
2828
type = "increment"
2929
mode = "local"
3030
input { ["v"] = "x" }
31+
output { new ContextVariableReferenceDescription { reference = "s" } }
3132
emits { new Internal { topic = "e2" } }
3233
}
3334
}
34-
exit { new Assign { expression = "e = true" } }
35+
exit {
36+
new Assign { expression = "e = true" }
37+
new Assign { expression = "f = f + s" }
38+
}
3539
on {
3640
["e2"] = new Transition {
3741
to = "c"
@@ -70,10 +74,13 @@ collaborativeStateMachine {
7074
}
7175
["e"] = new Terminal { entry { new Assign { expression = "b = true" } } }
7276
}
73-
transient { ["x"] = "0" }
77+
transient {
78+
["x"] = "0"
79+
["s"] = "0"
80+
}
7481
}
7582
}
76-
persistent { ["b"] = "false"; ["v"] = "0"; ["e"] = "false" }
83+
persistent { ["b"] = "false"; ["v"] = "0"; ["e"] = "false"; ["f"] = "0" }
7784
}
7885
instances {
7986
["complete"] = new Instance { stateMachineName = "completeStateMachine" }

0 commit comments

Comments
 (0)