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
Observe* = dataspace.Observe[Ref]
PublishProc = proc (turn: var Turn; v: Assertion; h: Handle) {.closure.}
RetractProc = proc (turn: var Turn; h: Handle) {.closure.}
MessageProc = proc (turn: var Turn; v: Assertion) {.closure.}
PublishProc = proc (turn: var Turn; v: Assertion; h: Handle) {.closure, gcsafe.}
RetractProc = proc (turn: var Turn; h: Handle) {.closure, gcsafe.}
MessageProc = proc (turn: var Turn; v: Assertion) {.closure, gcsafe.}
ClosureEntity = ref object of Entity
publishImpl: PublishProc
retractImpl: RetractProc
messageImpl: MessageProc
method publish(e: ClosureEntity; turn: var Turn; v: Assertion; h: Handle) =
if not e.publishImpl.isNil: e.publishImpl(turn, v, h)
method publish(e: ClosureEntity; turn: var Turn; a: AssertionRef; h: Handle) {.gcsafe.} =
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)
method message(e: ClosureEntity; turn: var Turn; v: Assertion) =
if not e.messageImpl.isNil: e.messageImpl(turn, v)
method message(e: ClosureEntity; turn: var Turn; a: AssertionRef) {.gcsafe.} =
if not e.messageImpl.isNil: e.messageImpl(turn, a.value)
proc argumentCount(handler: NimNode): int =
handler.expectKind {nnkDo, nnkStmtList}

View File

@ -7,8 +7,6 @@ import ../syndicate/protocols/[protocol, sturdy]
export Handle
# proc `==`*(x, y: Handle): bool {.borrow.}
template generateIdType(T: untyped) =
type T* = distinct Natural
proc `==`*(x, y: T): bool {.borrow.}
@ -20,11 +18,6 @@ generateIdType(EndpointId)
generateIdType(FieldId)
generateIdType(TurnId)
#[
proc genId(T: type): T =
getMonotime().ticks.T
]#
type
Attenuation = sturdy.Attenuation[Ref]
Oid = sturdy.Oid
@ -78,17 +71,22 @@ type
inertCheckPreventers: int
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
actor: Actor
facet: Facet
turn: var Turn
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 catLabels(f: Facet; labels: var string) =
labels.add ':'
@ -243,14 +241,14 @@ proc runRewrites*(a: Attenuation; v: Assertion): Assertion =
if result.isFalse: break
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:
let e = OutboundAssertion(
handle: h, peer: r, established: false)
turn.facet.outbound[h] = e
enqueue(turn, r.relay) do (turn: var Turn):
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 =
result = turn.facet.nextHandle()
@ -271,10 +269,10 @@ proc retract*(turn: var Turn; h: Handle) =
turn.retract(e)
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:
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) =
message(turn, r, toPreserve(v, Ref))

View File

@ -16,14 +16,14 @@ type
index: Index
handleMap: Table[Handle, Assertion]
method publish(ds: Dataspace; turn: var Turn; v: Assertion; h: Handle) =
if add(ds.index, turn, v):
method publish(ds: Dataspace; turn: var Turn; a: AssertionRef; h: Handle) {.gcsafe.} =
if add(ds.index, turn, a.value):
var obs: Observe
if obs.fromPreserve v:
if obs.fromPreserve a.value:
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:
let v = ds.handleMap[h]
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)
except KeyError: discard
method message(ds: Dataspace; turn: var Turn; v: Assertion) =
ds.index.deliverMessage(turn, v)
method message(ds: Dataspace; turn: var Turn; a: AssertionRef) {.gcsafe.} =
ds.index.deliverMessage(turn, a.value)
proc newDataspace*(turn: var Turn): Ref =
newRef(turn, Dataspace(index: initIndex()))

View File

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

View File

@ -53,18 +53,18 @@ type
proc releaseRefOut(r: Relay; e: WireSymbol) =
r.exported.drop e
method publish(spe: SyncPeerEntity; t: var Turn; v: Assertion; h: Handle) =
spe.handleMap[h] = publish(t, spe.peer, v)
method publish(spe: SyncPeerEntity; t: var Turn; a: AssertionRef; h: Handle) =
spe.handleMap[h] = publish(t, spe.peer, a.value)
method retract(se: SyncPeerEntity; t: var Turn; h: Handle) =
var other: Handle
if se.handleMap.pop(h, 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:
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) =
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))
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]
result.rewritten = contract(v) do (r: Ref) -> Value:
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) =
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(
orKind: EventKind.Assert,
`assert`: protocol.Assert(
assertion: re.relay.register(v, h),
assertion: re.relay.register(a.value, 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.send Event(
orKind: EventKind.Retract,
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,
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
peerEntity = newSyncPeerEntity(re.relay, peer)
exported: seq[WireSymbol]
@ -181,7 +181,7 @@ proc rewriteRefIn(relay; facet; n: WireRef, imported: var seq[WireSymbol]): Ref
else: raiseAssert "attenuation not implemented"
proc rewriteIn(relay; facet; v: Value):
tuple[rewritten: Assertion; imported: seq[WireSymbol]] =
tuple[rewritten: Assertion; imported: seq[WireSymbol]] {.gcsafe.} =
var imported: seq[WireSymbol]
result.rewritten = expand(v) do (pr: Value) -> Assertion:
var wr: WireRef
@ -192,7 +192,7 @@ proc rewriteIn(relay; facet; v: Value):
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
of EventKind.Assert:
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
]#
proc dispatch*(relay: Relay; v: Value) =
proc dispatch*(relay: Relay; v: Value) {.gcsafe.} =
trace "S: ", v
run(relay.facet) do (t: var Turn):
var pkt: Packet

View File

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