Track external tasks that will drive dataspace

This commit is contained in:
Emery Hemingway 2021-07-09 11:38:53 +02:00
parent 3dfafd925d
commit 262a8d7452
2 changed files with 35 additions and 8 deletions

View File

@ -14,7 +14,9 @@ export dataspaces.`==`
export dataspaces.addEndpoint
export dataspaces.addStartScript
export dataspaces.addStopScript
export dataspaces.beginExternalTask
export dataspaces.defineObservableProperty
export dataspaces.endExternalTask
export dataspaces.generateId
export dataspaces.hash
export dataspaces.recordDamage

View File

@ -92,6 +92,8 @@ type
dataspace: Dataspace
stopHandlers: seq[StopHandler]
future: Future[void]
externalTaskCount: int
stepScheduled: bool
ParentFacet = Option[Facet]
@ -524,16 +526,39 @@ proc stop*(facet; continuation: Script[void] = nil) =
proc addStopHandler*(g: Ground; h: StopHandler) =
g.stopHandlers.add(h)
proc step(g: Ground) =
if g.dataspace.runTasks():
proc step(g: Ground) {.gcsafe.}
proc scheduleStep(g: Ground) =
if not g.stepScheduled:
g.stepScheduled = true
asyncdispatch.callSoon: step(g)
proc beginExternalTask*(facet) =
## Inform the ``Ground`` dataspace of a pending external task.
## The dataspace will continue to operate until all internal
## and external tasks have completed. See ``endExternalTask``.
inc facet.actor.dataspace.ground.externalTaskCount
proc endExternalTask*(facet) =
## Inform the ``Ground`` dataspace that an external task has completed.
# TODO: automatically do this when the facet stops?
let g = facet.actor.dataspace.ground
dec g.externalTaskCount
scheduleStep g
proc step(g: Ground) =
# TODO: backgroundtasks
g.stepScheduled = false
if g.dataspace.runTasks():
scheduleStep g
else:
for actor in g.dataspace.actors.values:
terminate(actor, false)
for sh in g.stopHandlers:
sh(g.dataspace)
reset g.stopHandlers
complete(g.future)
if g.externalTaskCount < 1:
for actor in g.dataspace.actors.values:
terminate(actor, false)
for sh in g.stopHandlers:
sh(g.dataspace)
reset g.stopHandlers
complete(g.future)
proc bootModule*(name: string; bootProc: ActivationScript): Future[void] =
# TODO: better integration with the async dispatcher