macros: add onStart and onStop
The onStart and onStop macros will be called as actors start and stop. This can be used to call `quit`, since the async dispatcher will run empty and raise an error otherwise.
This commit is contained in:
parent
300f0169bb
commit
50afa0107f
|
@ -11,6 +11,8 @@ export dataspaces.Facet
|
|||
export dataspaces.FieldId
|
||||
export dataspaces.Fields
|
||||
export dataspaces.addEndpoint
|
||||
export dataspaces.addStartScript
|
||||
export dataspaces.addStopScript
|
||||
export dataspaces.defineObservableProperty
|
||||
export dataspaces.generateId
|
||||
export dataspaces.hash
|
||||
|
@ -178,4 +180,4 @@ template syndicate*(name: string; dataspaceBody: untyped): untyped =
|
|||
proc bootProc(rootFacet: Facet) =
|
||||
proc getCurrentFacet(): Facet {.inject, used.} = rootFacet
|
||||
dataspaceBody
|
||||
waitFor bootModule(name, bootProc)
|
||||
asyncCheck bootModule(name, bootProc)
|
||||
|
|
|
@ -253,6 +253,8 @@ proc abort(facet; emitPatches: bool) =
|
|||
for child in facet.children.values:
|
||||
child.abort(emitPatches)
|
||||
facet.retractAssertionsAndSubscriptions(emitPatches)
|
||||
for s in facet.stopScripts: s(facet)
|
||||
# call stopScripts immediately
|
||||
|
||||
proc enqueueScriptAction(actor; action: Action) =
|
||||
actor.pendingActions.add(action)
|
||||
|
@ -342,10 +344,13 @@ proc scheduleScript*(facet; prio: Priority; script: Script[void]) =
|
|||
proc scheduleScript*(facet; script: Script[void]) =
|
||||
facet.actor.scheduleTask(pNormal, facet.wrap(script))
|
||||
|
||||
proc addStartScript(facet; s: Script[void]) =
|
||||
proc addStartScript*(facet; s: Script[void]) =
|
||||
facet.ensureFacetSetup("onStart")
|
||||
facet.scheduleScript(pNormal, s)
|
||||
|
||||
proc addStopScript*(facet; s: Script[void]) =
|
||||
facet.stopScripts.add(s)
|
||||
|
||||
proc addFacet(actor; parentFacet: Option[Facet]; bootScript: Script[void]; checkInScript = false) =
|
||||
if checkInScript and parentFacet.isSome:
|
||||
assert parentFacet.get.inScript
|
||||
|
@ -530,6 +535,8 @@ proc step(g: Ground) =
|
|||
if g.dataspace.runTasks():
|
||||
asyncdispatch.callSoon: step(g)
|
||||
else:
|
||||
for actor in g.dataspace.actors.values:
|
||||
terminate(actor, false)
|
||||
for sh in g.stopHandlers:
|
||||
sh(g.dataspace)
|
||||
reset g.stopHandlers
|
||||
|
|
|
@ -7,15 +7,17 @@ import syndicate
|
|||
const
|
||||
BoxState = RecordClass(label: symbol"box-state", arity: 1)
|
||||
SetBox = RecordClass(label: symbol"set-box", arity: 1)
|
||||
# TODO: hide RecordClass behind Assertion and Message types
|
||||
|
||||
syndicate "test_dsl":
|
||||
|
||||
spawn "box":
|
||||
field(currentValue, int, 0)
|
||||
assert(BoxState, currentValue)
|
||||
assert(BoxState, currentValue.get)
|
||||
stopIf currentValue.get == 10:
|
||||
echo "box: terminating"
|
||||
onMessage(SetBox) do (newValue: int):
|
||||
# The SetBox message is unpacked to `newValue: int`
|
||||
echo "box: taking on new value ", newValue
|
||||
currentValue.set(newValue)
|
||||
|
||||
|
@ -27,3 +29,9 @@ syndicate "test_dsl":
|
|||
send(SetBox, v+1)
|
||||
onRetracted(BoxState) do (_):
|
||||
echo "client: box state disappeared"
|
||||
onStop:
|
||||
quit(0) # Quit explicitly rather than let the dispatcher run empty.
|
||||
|
||||
runForever()
|
||||
# The dataspace is driven by the async dispatcher.
|
||||
# Without `runForever` this module would exit immediately.
|
||||
|
|
Loading…
Reference in New Issue