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.addEndpoint
export dataspaces.addStartScript export dataspaces.addStartScript
export dataspaces.addStopScript export dataspaces.addStopScript
export dataspaces.beginExternalTask
export dataspaces.defineObservableProperty export dataspaces.defineObservableProperty
export dataspaces.endExternalTask
export dataspaces.generateId export dataspaces.generateId
export dataspaces.hash export dataspaces.hash
export dataspaces.recordDamage export dataspaces.recordDamage

View File

@ -92,6 +92,8 @@ type
dataspace: Dataspace dataspace: Dataspace
stopHandlers: seq[StopHandler] stopHandlers: seq[StopHandler]
future: Future[void] future: Future[void]
externalTaskCount: int
stepScheduled: bool
ParentFacet = Option[Facet] ParentFacet = Option[Facet]
@ -524,16 +526,39 @@ proc stop*(facet; continuation: Script[void] = nil) =
proc addStopHandler*(g: Ground; h: StopHandler) = proc addStopHandler*(g: Ground; h: StopHandler) =
g.stopHandlers.add(h) g.stopHandlers.add(h)
proc step(g: Ground) = proc step(g: Ground) {.gcsafe.}
if g.dataspace.runTasks():
proc scheduleStep(g: Ground) =
if not g.stepScheduled:
g.stepScheduled = true
asyncdispatch.callSoon: step(g) 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: else:
for actor in g.dataspace.actors.values: if g.externalTaskCount < 1:
terminate(actor, false) for actor in g.dataspace.actors.values:
for sh in g.stopHandlers: terminate(actor, false)
sh(g.dataspace) for sh in g.stopHandlers:
reset g.stopHandlers sh(g.dataspace)
complete(g.future) reset g.stopHandlers
complete(g.future)
proc bootModule*(name: string; bootProc: ActivationScript): Future[void] = proc bootModule*(name: string; bootProc: ActivationScript): Future[void] =
# TODO: better integration with the async dispatcher # TODO: better integration with the async dispatcher