Make the Entity methods compatible with mm:orc

This commit is contained in:
Emery Hemingway 2022-12-21 22:59:16 -06:00
parent 47da042671
commit 589b0772e3
6 changed files with 48 additions and 50 deletions

View File

@ -43,22 +43,22 @@ export Actor, Assertion, Facet, Handle, Ref, Symbol, Turn, TurnAction,
type type
Observe* = dataspace.Observe[Ref] Observe* = dataspace.Observe[Ref]
PublishProc = proc (turn: var Turn; v: Assertion; h: Handle) {.closure.} PublishProc = proc (turn: var Turn; v: Assertion; h: Handle) {.closure, gcsafe.}
RetractProc = proc (turn: var Turn; h: Handle) {.closure.} RetractProc = proc (turn: var Turn; h: Handle) {.closure, gcsafe.}
MessageProc = proc (turn: var Turn; v: Assertion) {.closure.} MessageProc = proc (turn: var Turn; v: Assertion) {.closure, gcsafe.}
ClosureEntity = ref object of Entity ClosureEntity = ref object of Entity
publishImpl: PublishProc publishImpl: PublishProc
retractImpl: RetractProc retractImpl: RetractProc
messageImpl: MessageProc messageImpl: MessageProc
method publish(e: ClosureEntity; turn: var Turn; v: Assertion; h: Handle) = method publish(e: ClosureEntity; turn: var Turn; a: AssertionRef; h: Handle) {.gcsafe.} =
if not e.publishImpl.isNil: e.publishImpl(turn, v, h) if not e.publishImpl.isNil: e.publishImpl(turn, a.value, h)
method retract(e: ClosureEntity; turn: var Turn; h: Handle) = method retract(e: ClosureEntity; turn: var Turn; h: Handle) {.gcsafe.} =
if not e.retractImpl.isNil: e.retractImpl(turn, h) if not e.retractImpl.isNil: e.retractImpl(turn, h)
method message(e: ClosureEntity; turn: var Turn; v: Assertion) = method message(e: ClosureEntity; turn: var Turn; a: AssertionRef) {.gcsafe.} =
if not e.messageImpl.isNil: e.messageImpl(turn, v) if not e.messageImpl.isNil: e.messageImpl(turn, a.value)
proc argumentCount(handler: NimNode): int = proc argumentCount(handler: NimNode): int =
handler.expectKind {nnkDo, nnkStmtList} handler.expectKind {nnkDo, nnkStmtList}

View File

@ -7,8 +7,6 @@ import ../syndicate/protocols/[protocol, sturdy]
export Handle export Handle
# proc `==`*(x, y: Handle): bool {.borrow.}
template generateIdType(T: untyped) = template generateIdType(T: untyped) =
type T* = distinct Natural type T* = distinct Natural
proc `==`*(x, y: T): bool {.borrow.} proc `==`*(x, y: T): bool {.borrow.}
@ -20,11 +18,6 @@ generateIdType(EndpointId)
generateIdType(FieldId) generateIdType(FieldId)
generateIdType(TurnId) generateIdType(TurnId)
#[
proc genId(T: type): T =
getMonotime().ticks.T
]#
type type
Attenuation = sturdy.Attenuation[Ref] Attenuation = sturdy.Attenuation[Ref]
Oid = sturdy.Oid Oid = sturdy.Oid
@ -78,17 +71,22 @@ type
inertCheckPreventers: int inertCheckPreventers: int
isAlive: bool isAlive: bool
type AssertionRef* = ref object
value*: Preserve[Ref]
# if the Enity methods take a Preserve[Ref] object then the generated
# C code has "redefinition of struct" problems when orc is enabled
method publish*(e: Entity; turn: var Turn; v: AssertionRef; h: Handle) {.base, gcsafe.} = discard
method retract*(e: Entity; turn: var Turn; h: Handle) {.base, gcsafe.} = discard
method message*(e: Entity; turn: var Turn; v: AssertionRef) {.base, gcsafe.} = discard
method sync*(e: Entity; turn: var Turn; peer: Ref) {.base, gcsafe.} = discard
using using
actor: Actor actor: Actor
facet: Facet facet: Facet
turn: var Turn turn: var Turn
action: TurnAction action: TurnAction
method publish*(e: Entity; turn: var Turn; v: Assertion; h: Handle) {.base.} = discard
method retract*(e: Entity; turn: var Turn; h: Handle) {.base.} = discard
method message*(e: Entity; turn: var Turn; v: Assertion) {.base.} = discard
method sync*(e: Entity; turn: var Turn; peer: Ref) {.base.} = discard
proc labels(f: Facet): string = proc labels(f: Facet): string =
proc catLabels(f: Facet; labels: var string) = proc catLabels(f: Facet; labels: var string) =
labels.add ':' labels.add ':'
@ -243,14 +241,14 @@ proc runRewrites*(a: Attenuation; v: Assertion): Assertion =
if result.isFalse: break if result.isFalse: break
proc publish(turn: var Turn; r: Ref; v: Assertion; h: Handle) = proc publish(turn: var Turn; r: Ref; v: Assertion; h: Handle) =
let a = runRewrites(r.attenuation, v) var a = runRewrites(r.attenuation, v)
if not a.isFalse: if not a.isFalse:
let e = OutboundAssertion( let e = OutboundAssertion(
handle: h, peer: r, established: false) handle: h, peer: r, established: false)
turn.facet.outbound[h] = e turn.facet.outbound[h] = e
enqueue(turn, r.relay) do (turn: var Turn): enqueue(turn, r.relay) do (turn: var Turn):
e.established = true e.established = true
publish(r.target, turn, a, e.handle) publish(r.target, turn, AssertionRef(value: a), e.handle)
proc publish*(turn: var Turn; r: Ref; a: Assertion): Handle = proc publish*(turn: var Turn; r: Ref; a: Assertion): Handle =
result = turn.facet.nextHandle() result = turn.facet.nextHandle()
@ -271,10 +269,10 @@ proc retract*(turn: var Turn; h: Handle) =
turn.retract(e) turn.retract(e)
proc message*(turn: var Turn; r: Ref; v: Assertion) = proc message*(turn: var Turn; r: Ref; v: Assertion) =
let a = runRewrites(r.attenuation, v) var a = runRewrites(r.attenuation, v)
if not a.isFalse: if not a.isFalse:
enqueue(turn, r.relay) do (turn: var Turn): enqueue(turn, r.relay) do (turn: var Turn):
r.target.message(turn, a) r.target.message(turn, AssertionRef(value: a))
proc message*[T](turn: var Turn; r: Ref; v: T) = proc message*[T](turn: var Turn; r: Ref; v: T) =
message(turn, r, toPreserve(v, Ref)) message(turn, r, toPreserve(v, Ref))

View File

@ -16,14 +16,14 @@ type
index: Index index: Index
handleMap: Table[Handle, Assertion] handleMap: Table[Handle, Assertion]
method publish(ds: Dataspace; turn: var Turn; v: Assertion; h: Handle) = method publish(ds: Dataspace; turn: var Turn; a: AssertionRef; h: Handle) {.gcsafe.} =
if add(ds.index, turn, v): if add(ds.index, turn, a.value):
var obs: Observe var obs: Observe
if obs.fromPreserve v: if obs.fromPreserve a.value:
ds.index.add(turn, obs.pattern, obs.observer) ds.index.add(turn, obs.pattern, obs.observer)
ds.handleMap[h] = v ds.handleMap[h] = a.value
method retract(ds: Dataspace; turn: var Turn; h: Handle) = method retract(ds: Dataspace; turn: var Turn; h: Handle) {.gcsafe.} =
try: try:
let v = ds.handleMap[h] let v = ds.handleMap[h]
if remove(ds.index, turn, v): if remove(ds.index, turn, v):
@ -33,8 +33,8 @@ method retract(ds: Dataspace; turn: var Turn; h: Handle) =
ds.index.remove(turn, obs.pattern, obs.observer) ds.index.remove(turn, obs.pattern, obs.observer)
except KeyError: discard except KeyError: discard
method message(ds: Dataspace; turn: var Turn; v: Assertion) = method message(ds: Dataspace; turn: var Turn; a: AssertionRef) {.gcsafe.} =
ds.index.deliverMessage(turn, v) ds.index.deliverMessage(turn, a.value)
proc newDataspace*(turn: var Turn): Ref = proc newDataspace*(turn: var Turn): Ref =
newRef(turn, Dataspace(index: initIndex())) newRef(turn, Dataspace(index: initIndex()))

View File

@ -23,8 +23,8 @@ type
cb: DuringProc cb: DuringProc
assertionMap: Table[Handle, DuringAction] assertionMap: Table[Handle, DuringAction]
method publish(de: DuringEntity; turn: var Turn; a: Assertion; h: Handle) = method publish(de: DuringEntity; turn: var Turn; a: AssertionRef; h: Handle) =
let action = de.cb(turn, a, h) let action = de.cb(turn, a.value, h)
# assert(not action.isNil "should have put in a no-op action") # assert(not action.isNil "should have put in a no-op action")
let g = de.assertionMap.getOrDefault h let g = de.assertionMap.getOrDefault h
case g.kind case g.kind

View File

@ -53,18 +53,18 @@ type
proc releaseRefOut(r: Relay; e: WireSymbol) = proc releaseRefOut(r: Relay; e: WireSymbol) =
r.exported.drop e r.exported.drop e
method publish(spe: SyncPeerEntity; t: var Turn; v: Assertion; h: Handle) = method publish(spe: SyncPeerEntity; t: var Turn; a: AssertionRef; h: Handle) =
spe.handleMap[h] = publish(t, spe.peer, v) spe.handleMap[h] = publish(t, spe.peer, a.value)
method retract(se: SyncPeerEntity; t: var Turn; h: Handle) = method retract(se: SyncPeerEntity; t: var Turn; h: Handle) =
var other: Handle var other: Handle
if se.handleMap.pop(h, other): if se.handleMap.pop(h, other):
retract(t, other) retract(t, other)
method message(se: SyncPeerEntity; t: var Turn; v: Assertion) = method message(se: SyncPeerEntity; t: var Turn; a: AssertionRef) =
if not se.e.isNil: if not se.e.isNil:
se.relay.releaseRefOut(se.e) se.relay.releaseRefOut(se.e)
message(t, se.peer, v) message(t, se.peer, a.value)
method sync(se: SyncPeerEntity; t: var Turn; peer: Ref) = method sync(se: SyncPeerEntity; t: var Turn; peer: Ref) =
sync(t, se.peer, peer) sync(t, se.peer, peer)
@ -87,7 +87,7 @@ proc rewriteRefOut(relay: Relay; `ref`: Ref; transient: bool; exported: var seq[
mine: WireRefMine(oid: ws.oid)) mine: WireRefMine(oid: ws.oid))
proc rewriteOut(relay: Relay; v: Assertion; transient: bool): proc rewriteOut(relay: Relay; v: Assertion; transient: bool):
tuple[rewritten: Value, exported: seq[WireSymbol]] = tuple[rewritten: Value, exported: seq[WireSymbol]] {.gcsafe.} =
var exported: seq[WireSymbol] var exported: seq[WireSymbol]
result.rewritten = contract(v) do (r: Ref) -> Value: result.rewritten = contract(v) do (r: Ref) -> Value:
rewriteRefOut(relay, r, transient, exported).toPreserve rewriteRefOut(relay, r, transient, exported).toPreserve
@ -124,24 +124,24 @@ proc send(r: Relay; rOid: protocol.Oid; m: Event) =
proc send(re: RelayEntity; ev: Event) = proc send(re: RelayEntity; ev: Event) =
send(re.relay, protocol.Oid re.oid, ev) send(re.relay, protocol.Oid re.oid, ev)
method publish(re: RelayEntity; t: var Turn; v: Assertion; h: Handle) = method publish(re: RelayEntity; t: var Turn; a: AssertionRef; h: Handle) {.gcsafe.} =
re.send Event( re.send Event(
orKind: EventKind.Assert, orKind: EventKind.Assert,
`assert`: protocol.Assert( `assert`: protocol.Assert(
assertion: re.relay.register(v, h), assertion: re.relay.register(a.value, h),
handle: h)) handle: h))
method retract(re: RelayEntity; t: var Turn; h: Handle) = method retract(re: RelayEntity; t: var Turn; h: Handle) {.gcsafe.} =
re.relay.deregister h re.relay.deregister h
re.send Event( re.send Event(
orKind: EventKind.Retract, orKind: EventKind.Retract,
retract: Retract(handle: h)) retract: Retract(handle: h))
method message(re: RelayEntity; turn: var Turn; msg: Assertion) = method message(re: RelayEntity; turn: var Turn; msg: AssertionRef) {.gcsafe.} =
re.send Event(orKind: EventKind.Message, re.send Event(orKind: EventKind.Message,
message: Message(body: register(re.relay, msg))) message: Message(body: register(re.relay, msg.value)))
method sync(re: RelayEntity; turn: var Turn; peer: Ref) = method sync(re: RelayEntity; turn: var Turn; peer: Ref) {.gcsafe.} =
var var
peerEntity = newSyncPeerEntity(re.relay, peer) peerEntity = newSyncPeerEntity(re.relay, peer)
exported: seq[WireSymbol] exported: seq[WireSymbol]
@ -181,7 +181,7 @@ proc rewriteRefIn(relay; facet; n: WireRef, imported: var seq[WireSymbol]): Ref
else: raiseAssert "attenuation not implemented" else: raiseAssert "attenuation not implemented"
proc rewriteIn(relay; facet; v: Value): proc rewriteIn(relay; facet; v: Value):
tuple[rewritten: Assertion; imported: seq[WireSymbol]] = tuple[rewritten: Assertion; imported: seq[WireSymbol]] {.gcsafe.} =
var imported: seq[WireSymbol] var imported: seq[WireSymbol]
result.rewritten = expand(v) do (pr: Value) -> Assertion: result.rewritten = expand(v) do (pr: Value) -> Assertion:
var wr: WireRef var wr: WireRef
@ -192,7 +192,7 @@ proc rewriteIn(relay; facet; v: Value):
proc close(r: Relay) = discard proc close(r: Relay) = discard
proc dispatch*(relay: Relay; turn: var Turn; `ref`: Ref; event: Event) = proc dispatch*(relay: Relay; turn: var Turn; `ref`: Ref; event: Event) {.gcsafe.} =
case event.orKind case event.orKind
of EventKind.Assert: of EventKind.Assert:
let (a, imported) = rewriteIn(relay, turn.facet, event.assert.assertion) let (a, imported) = rewriteIn(relay, turn.facet, event.assert.assertion)
@ -220,7 +220,7 @@ proc dispatch*(relay: Relay; turn: var Turn; `ref`: Ref; event: Event) =
for e in imported: relay.imported.del e for e in imported: relay.imported.del e
]# ]#
proc dispatch*(relay: Relay; v: Value) = proc dispatch*(relay: Relay; v: Value) {.gcsafe.} =
trace "S: ", v trace "S: ", v
run(relay.facet) do (t: var Turn): run(relay.facet) do (t: var Turn):
var pkt: Packet var pkt: Packet

View File

@ -64,9 +64,9 @@ func isEmpty(leaf: Leaf): bool =
leaf.cachedAssertions.len == 0 and leaf.observerGroups.len == 0 leaf.cachedAssertions.len == 0 and leaf.observerGroups.len == 0
type type
ContinuationProc = proc (c: Continuation; v: Value) ContinuationProc = proc (c: Continuation; v: Value) {.gcsafe.}
LeafProc = proc (l: Leaf; v: Value) LeafProc = proc (l: Leaf; v: Value) {.gcsafe.}
ObserverProc = proc (turn: var Turn; group: ObserverGroup; vs: seq[Value]) ObserverProc = proc (turn: var Turn; group: ObserverGroup; vs: seq[Value]) {.gcsafe.}
type TermStack = SinglyLinkedList[Value] type TermStack = SinglyLinkedList[Value]