From b83ef93484482233102848b6ffd1b98fd9281ebd Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Thu, 15 Feb 2024 19:50:11 +0000 Subject: [PATCH] Handler attempt --- src/syndicate.nim | 15 +++++++++ src/syndicate/actors.nim | 70 ++++++++++++++++++++++------------------ tests/test_timers.nim | 3 +- 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/src/syndicate.nim b/src/syndicate.nim index 49295ae..ea31c78 100644 --- a/src/syndicate.nim +++ b/src/syndicate.nim @@ -4,6 +4,7 @@ ## This module implements the `Syndicate DSL `_. import std/[macros, tables, typetraits] +import pkg/cps # import pkg/sys/ioqueue import preserves @@ -206,3 +207,17 @@ proc runActor*(name: string; bootProc: DeprecatedBootProc) {.deprecated.} = runActor(name) do (turn: Turn, ds: Cap): bootProc(ds, turn) ]# + +proc wrapHandler(body: NimNode; ident: string): NimNode = + var sym = genSym(nskProc, ident) + quote do: + proc `sym`() = + `body` + +macro onStop*(body: untyped) = + let + handler = wrapHandler(body, "onStop") + handlerSym = handler[0] + quote do: + `handler` + addStopHandler(activeActor(), `handlerSym`) diff --git a/src/syndicate/actors.nim b/src/syndicate/actors.nim index 9364412..6d61c25 100644 --- a/src/syndicate/actors.nim +++ b/src/syndicate/actors.nim @@ -17,25 +17,32 @@ when traceSyndicate: export protocol.Handle type - Actor* = ref object - ## https://synit.org/book/glossary.html#actor - root: Facet - handleAllocator: Handle - id: ActorId - when traceSyndicate: - traceStream: FileStream - stopped: bool + Cont* = ref object of Continuation + turn: Turn + + Handler* = proc() {.closure.} + + Work = Deque[Cont] + + FacetState = enum fIdle, fRunning, fStopped Facet* = ref object ## https://synit.org/book/glossary.html#facet actor: Actor parent: Facet - stopHandlers: Work - state: FacetState + stopHandlers: Deque[Handler] + # state: FacetState when traceSyndicate: id: FacetId - FacetState = enum fIdle, fRunning, fStopped + Turn* = ref object + ## https://synit.org/book/glossary.html#turn + facet: Facet + entity: Entity + event: Option[protocol.Event] + work: Work + when traceSyndicate: + desc: TurnDescription Entity* = ref object of RootObj ## https://synit.org/book/glossary.html#entity @@ -49,19 +56,16 @@ type target*: Entity attenuation*: seq[sturdy.Caveat] - Turn* = ref object - ## https://synit.org/book/glossary.html#turn - facet: Facet - entity: Entity - event: Option[protocol.Event] - work: Work + Actor* = ref object + ## https://synit.org/book/glossary.html#actor + # crashHandlers: Deque[Handler] + root: Facet + handleAllocator: Handle + facetIdAllocator: int + id: ActorId when traceSyndicate: - desc: TurnDescription - - Work = Deque[Cont] - - Cont* = ref object of Continuation - turn: Turn + traceStream: FileStream + stopped: bool using actor: Actor @@ -74,14 +78,12 @@ proc hash*(facet): Hash = facet.unsafeAddr.hash proc hash*(cap): Hash = cap.unsafeAddr.hash proc newFacet(actor: Actor; parent: Facet): Facet = + inc(actor.facetIdAllocator) result = Facet( actor: actor, parent: parent, + id: actor.facetIdAllocator.toPreserves, ) - when traceSyndicate: - if not parent.isNil: - result.id = parent.id - inc(result.id.register) proc newActor(name: string): Actor = result = Actor(id: name.toPreserves) @@ -126,9 +128,7 @@ when traceSyndicate: ) proc newExternalTurn(facet): Turn = - result = Turn( - facet: facet, - ) + result = Turn(facet: facet) when traceSyndicate: result.desc = TurnDescription(cause: TurnCause(orKind: TurnCauseKind.external)) @@ -170,6 +170,11 @@ proc run(turn) = if actor.stopped: trace(actor, ActorActivation(orkind: ActorActivationKind.stop)) +proc run(handlers: var Deque[Handler]) = + while handlers.len > 0: + var h = handlers.popLast() + h() + proc start(actor; cont: Cont) = when traceSyndicate: var act = ActorActivation(orkind: ActorActivationKind.start) @@ -186,7 +191,7 @@ proc collectPath(result: var seq[FacetId]; facet) = result.add(facet.id) proc stop(turn; facet; reason: FacetStopReason) = - run(facet, facet.stopHandlers) + run(facet.stopHandlers) when traceSyndicate: var act = ActionDescription(orKind: ActionDescriptionKind.facetstop) collectPath(act.facetstop.path, facet) @@ -313,3 +318,6 @@ proc message*(cap: Cap; val: Value) {.syndicate.} = proc sync*(cap: Cap) {.syndicate.} = activeTurn().sync(cap) + +proc addStopHandler*(actor: Actor; h: Handler) = + actor.root.stopHandlers.addLast(h) diff --git a/tests/test_timers.nim b/tests/test_timers.nim index d5a240f..46d502e 100644 --- a/tests/test_timers.nim +++ b/tests/test_timers.nim @@ -17,7 +17,7 @@ proc main() {.syndicate.} = sync(ds) onStop: - echo "onStop body is executing" + echo "anonymous stop handler was invoked" echo "stopping actor" stopActor() @@ -38,4 +38,5 @@ proc main() {.syndicate.} = stopActor() ]# + bootActor("main", whelp main())