Rename Ref to Cap
This commit is contained in:
parent
4e0a36ef31
commit
ce8e800187
|
@ -17,7 +17,7 @@ when defined(posix):
|
|||
|
||||
export patterns
|
||||
|
||||
export Actor, Assertion, Facet, Handle, Ref, Symbol, Turn, TurnAction,
|
||||
export Actor, Assertion, Facet, Handle, Cap, Ref, Symbol, Turn, TurnAction,
|
||||
`$`, addCallback, analyse, asyncCheck, bootDataspace,
|
||||
facet, future, inFacet, message, newDataspace, onStop, publish,
|
||||
retract, replace, run, spawn, stop, unembed, unpackLiterals
|
||||
|
@ -38,7 +38,7 @@ proc `?`*[T](val: T): Pattern {.inline.} =
|
|||
patterns.grab[T](val)
|
||||
|
||||
type
|
||||
Observe* = dataspace.Observe[Ref]
|
||||
Observe* = dataspace.Observe[Cap]
|
||||
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.}
|
||||
|
@ -136,7 +136,7 @@ proc wrapDuringHandler(turn, entryBody, exitBody: NimNode): NimNode =
|
|||
`exitBody`
|
||||
result = action
|
||||
|
||||
macro onPublish*(turn: untyped; ds: Ref; pattern: Pattern; handler: untyped) =
|
||||
macro onPublish*(turn: untyped; ds: Cap; pattern: Pattern; handler: untyped) =
|
||||
## Call `handler` when an assertion matching `pattern` is published at `ds`.
|
||||
let
|
||||
argCount = argumentCount(handler)
|
||||
|
@ -148,7 +148,7 @@ macro onPublish*(turn: untyped; ds: Ref; pattern: Pattern; handler: untyped) =
|
|||
`handlerProc`
|
||||
discard observe(`turn`, `ds`, `pattern`, ClosureEntity(publishImpl: `handlerSym`))
|
||||
|
||||
macro onMessage*(turn: untyped; ds: Ref; pattern: Pattern; handler: untyped) =
|
||||
macro onMessage*(turn: untyped; ds: Cap; pattern: Pattern; handler: untyped) =
|
||||
## Call `handler` when an message matching `pattern` is broadcasted at `ds`.
|
||||
let
|
||||
argCount = argumentCount(handler)
|
||||
|
@ -160,7 +160,7 @@ macro onMessage*(turn: untyped; ds: Ref; pattern: Pattern; handler: untyped) =
|
|||
`handlerProc`
|
||||
discard observe(`turn`, `ds`, `pattern`, ClosureEntity(messageImpl: `handlerSym`))
|
||||
|
||||
macro during*(turn: untyped; ds: Ref; pattern: Pattern; publishBody, retractBody: untyped) =
|
||||
macro during*(turn: untyped; ds: Cap; pattern: Pattern; publishBody, retractBody: untyped) =
|
||||
## Call `publishBody` when an assertion matching `pattern` is published to `ds` and
|
||||
## call `retractBody` on retraction. Assertions that match `pattern` but are not
|
||||
## convertable to the arguments of `publishBody` are silently discarded.
|
||||
|
@ -178,7 +178,7 @@ macro during*(turn: untyped; ds: Ref; pattern: Pattern; publishBody, retractBody
|
|||
`callbackProc`
|
||||
discard observe(`turn`, `ds`, `pattern`, during(`callbackSym`))
|
||||
|
||||
macro during*(turn: untyped; ds: Ref; pattern: Pattern; publishBody: untyped) =
|
||||
macro during*(turn: untyped; ds: Cap; pattern: Pattern; publishBody: untyped) =
|
||||
## Variant of `during` without a retract body.
|
||||
let
|
||||
argCount = argumentCount(publishBody)
|
||||
|
@ -190,7 +190,7 @@ macro during*(turn: untyped; ds: Ref; pattern: Pattern; publishBody: untyped) =
|
|||
`callbackProc`
|
||||
discard observe(`turn`, `ds`, `pattern`, during(`callbackSym`))
|
||||
|
||||
type BootProc = proc (ds: Ref; turn: var Turn) {.gcsafe.}
|
||||
type BootProc = proc (ds: Cap; turn: var Turn) {.gcsafe.}
|
||||
|
||||
proc runActor*(name: string; bootProc: BootProc) =
|
||||
## Run an `Actor` to completion.
|
||||
|
|
|
@ -27,27 +27,29 @@ generateIdType(TurnId)
|
|||
|
||||
type
|
||||
Oid = sturdy.Oid
|
||||
Assertion* = Preserve[Ref]
|
||||
Caveat = sturdy.Caveat[Ref]
|
||||
Assertion* = Preserve[Cap]
|
||||
Caveat = sturdy.Caveat[Cap]
|
||||
Attenuation = seq[Caveat]
|
||||
Rewrite = sturdy.Rewrite[Ref]
|
||||
Rewrite = sturdy.Rewrite[Cap]
|
||||
|
||||
AssertionRef* = ref object
|
||||
value*: Preserve[Ref]
|
||||
# if the Enity methods take a Preserve[Ref] object then the generated
|
||||
value*: Preserve[Cap]
|
||||
# if the Enity methods take a Preserve[Cap] object then the generated
|
||||
# C code has "redefinition of struct" problems when orc is enabled
|
||||
|
||||
Entity* = ref object of RootObj
|
||||
oid*: Oid # oid is how Entities are identified over the wire
|
||||
|
||||
Ref* {.unpreservable.} = ref object # TODO: rename
|
||||
Cap* {.unpreservable.} = ref object
|
||||
relay*: Facet
|
||||
target*: Entity
|
||||
attenuation*: Attenuation
|
||||
|
||||
Ref* {.deprecated: "Ref was renamed to Cap".} = Cap
|
||||
|
||||
OutboundAssertion = ref object
|
||||
handle: Handle
|
||||
peer: Ref
|
||||
peer: Cap
|
||||
established: bool
|
||||
OutboundTable = Table[Handle, OutboundAssertion]
|
||||
|
||||
|
@ -111,7 +113,7 @@ when tracing:
|
|||
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
|
||||
method sync*(e: Entity; turn: var Turn; peer: Cap) {.base, gcsafe.} = discard
|
||||
|
||||
using
|
||||
actor: Actor
|
||||
|
@ -133,15 +135,15 @@ proc labels(f: Facet): string =
|
|||
proc `$`*(f: Facet): string =
|
||||
"<Facet:" & f.labels & ">"
|
||||
|
||||
proc `$`*(r: Ref): string =
|
||||
proc `$`*(r: Cap): string =
|
||||
"<Ref:" & r.relay.labels & ">"
|
||||
|
||||
proc `$`*(actor: Actor): string =
|
||||
"<Actor:" & actor.name & ">" # TODO: ambigous
|
||||
|
||||
proc attenuate(r: Ref; a: Attenuation): Ref =
|
||||
proc attenuate(r: Cap; a: Attenuation): Cap =
|
||||
if a.len == 0: result = r
|
||||
else: result = Ref(
|
||||
else: result = Cap(
|
||||
relay: r.relay,
|
||||
target: r.target,
|
||||
attenuation: a & r.attenuation)
|
||||
|
@ -149,7 +151,7 @@ proc attenuate(r: Ref; a: Attenuation): Ref =
|
|||
proc hash*(facet): Hash =
|
||||
facet.id.hash
|
||||
|
||||
proc hash*(r: Ref): Hash = !$(r.relay.hash !& r.target.unsafeAddr.hash)
|
||||
proc hash*(r: Cap): Hash = !$(r.relay.hash !& r.target.unsafeAddr.hash)
|
||||
|
||||
proc nextHandle(facet: Facet): Handle =
|
||||
result = succ(facet.actor.handleAllocator[])
|
||||
|
@ -163,7 +165,7 @@ proc enqueue(turn: var Turn; target: Facet; action: TurnAction) =
|
|||
else:
|
||||
turn.queues[target] = @[action]
|
||||
|
||||
type Bindings = Table[Preserve[Ref], Preserve[Ref]]
|
||||
type Bindings = Table[Preserve[Cap], Preserve[Cap]]
|
||||
|
||||
proc match(bindings: var Bindings; p: Pattern; v: Assertion): bool =
|
||||
case p.orKind
|
||||
|
@ -181,7 +183,7 @@ proc match(bindings: var Bindings; p: Pattern; v: Assertion): bool =
|
|||
result = v.isEmbedded
|
||||
of PatternKind.Pbind:
|
||||
if match(bindings, p.pbind.pattern, v):
|
||||
bindings[toPreserve(p.pbind.pattern, Ref)] = v
|
||||
bindings[toPreserve(p.pbind.pattern, Cap)] = v
|
||||
result = true
|
||||
of PatternKind.Pand:
|
||||
for pp in p.pand.patterns:
|
||||
|
@ -233,7 +235,7 @@ proc instantiate(t: Template; bindings: Bindings): Assertion =
|
|||
result = embed(attenuate(v.embed, t.tattenuate.attenuation))
|
||||
of TemplateKind.TRef:
|
||||
let n = $t.tref.binding.int
|
||||
try: result = bindings[toPreserve(n, Ref)]
|
||||
try: result = bindings[toPreserve(n, Cap)]
|
||||
except KeyError:
|
||||
raise newException(ValueError, "unbound reference: " & n)
|
||||
of TemplateKind.Lit:
|
||||
|
@ -245,11 +247,11 @@ proc instantiate(t: Template; bindings: Bindings): Assertion =
|
|||
for i, tt in t.tcompound.rec.fields:
|
||||
result[i] = instantiate(tt, bindings)
|
||||
of TCompoundKind.arr:
|
||||
result = initSequence(t.tcompound.arr.items.len, Ref)
|
||||
result = initSequence(t.tcompound.arr.items.len, Cap)
|
||||
for i, tt in t.tcompound.arr.items:
|
||||
result[i] = instantiate(tt, bindings)
|
||||
of TCompoundKind.dict:
|
||||
result = initDictionary(Ref)
|
||||
result = initDictionary(Cap)
|
||||
for key, tt in t.tcompound.dict.entries:
|
||||
result[key] = instantiate(tt, bindings)
|
||||
|
||||
|
@ -275,7 +277,7 @@ proc runRewrites*(a: Attenuation; v: Assertion): Assertion =
|
|||
result = examineAlternatives(stage, result)
|
||||
if result.isFalse: break
|
||||
|
||||
proc publish(turn: var Turn; r: Ref; v: Assertion; h: Handle) =
|
||||
proc publish(turn: var Turn; r: Cap; v: Assertion; h: Handle) =
|
||||
var a = runRewrites(r.attenuation, v)
|
||||
if not a.isFalse:
|
||||
let e = OutboundAssertion(
|
||||
|
@ -291,18 +293,18 @@ proc publish(turn: var Turn; r: Ref; v: Assertion; h: Handle) =
|
|||
act.enqueue.event.target.oid = r.target.oid.toPreserve
|
||||
act.enqueue.event.detail = trace.TurnEvent[void](orKind: TurnEventKind.assert)
|
||||
act.enqueue.event.detail.assert.assertion.value.value =
|
||||
contract(v) do (r: Ref) -> Preserve[void]:
|
||||
contract(v) do (r: Cap) -> Preserve[void]:
|
||||
discard
|
||||
act.enqueue.event.detail.assert.handle = h
|
||||
turn.desc.actions.add act
|
||||
|
||||
|
||||
proc publish*(turn: var Turn; r: Ref; a: Assertion): Handle =
|
||||
proc publish*(turn: var Turn; r: Cap; a: Assertion): Handle =
|
||||
result = turn.facet.nextHandle()
|
||||
publish(turn, r, a, result)
|
||||
|
||||
proc publish*[T](turn: var Turn; r: Ref; a: T): Handle =
|
||||
publish(turn, r, toPreserve(a, Ref))
|
||||
proc publish*[T](turn: var Turn; r: Cap; a: T): Handle =
|
||||
publish(turn, r, toPreserve(a, Cap))
|
||||
|
||||
proc retract(turn: var Turn; e: OutboundAssertion) =
|
||||
enqueue(turn, e.peer.relay) do (turn: var Turn):
|
||||
|
@ -315,31 +317,31 @@ proc retract*(turn: var Turn; h: Handle) =
|
|||
if turn.facet.outbound.pop(h, e):
|
||||
turn.retract(e)
|
||||
|
||||
proc message*(turn: var Turn; r: Ref; v: Assertion) =
|
||||
proc message*(turn: var Turn; r: Cap; v: Assertion) =
|
||||
var a = runRewrites(r.attenuation, v)
|
||||
if not a.isFalse:
|
||||
enqueue(turn, r.relay) do (turn: var Turn):
|
||||
r.target.message(turn, AssertionRef(value: a))
|
||||
|
||||
proc message*[T](turn: var Turn; r: Ref; v: T) =
|
||||
message(turn, r, toPreserve(v, Ref))
|
||||
proc message*[T](turn: var Turn; r: Cap; v: T) =
|
||||
message(turn, r, toPreserve(v, Cap))
|
||||
|
||||
proc sync(turn: var Turn; e: Entity; peer: Ref) =
|
||||
proc sync(turn: var Turn; e: Entity; peer: Cap) =
|
||||
e.sync(turn, peer)
|
||||
# or turn.message(peer, true) ?
|
||||
|
||||
proc sync*(turn: var Turn; r, peer: Ref) =
|
||||
proc sync*(turn: var Turn; r, peer: Cap) =
|
||||
enqueue(turn, r.relay) do (turn: var Turn):
|
||||
sync(turn, r.target, peer)
|
||||
|
||||
proc replace*[T](turn: var Turn; `ref`: Ref; h: Handle; v: T): Handle =
|
||||
result = publish(turn, `ref`, v)
|
||||
proc replace*[T](turn: var Turn; cap: Cap; h: Handle; v: T): Handle =
|
||||
result = publish(turn, cap, v)
|
||||
if h != default(Handle):
|
||||
retract(turn, h)
|
||||
|
||||
proc replace*[T](turn: var Turn; `ref`: Ref; h: var Handle; v: T): Handle {.discardable.} =
|
||||
proc replace*[T](turn: var Turn; cap: Cap; h: var Handle; v: T): Handle {.discardable.} =
|
||||
var old = h
|
||||
h = publish(turn, `ref`, v)
|
||||
h = publish(turn, cap, v)
|
||||
if old != default(Handle):
|
||||
retract(turn, old)
|
||||
h
|
||||
|
@ -475,9 +477,9 @@ proc spawn*(name: string; turn: var Turn; bootProc: TurnAction; initialAssertion
|
|||
run(actor, bootProc, newOutBound)
|
||||
actor
|
||||
|
||||
proc newInertRef*(): Ref =
|
||||
proc newInertCap*(): Cap =
|
||||
let a = bootActor("inert") do (turn: var Turn): turn.stop()
|
||||
Ref(relay: a.root)
|
||||
Cap(relay: a.root)
|
||||
|
||||
proc atExit*(actor; action) = actor.exitHooks.add action
|
||||
|
||||
|
@ -532,9 +534,9 @@ proc run*(facet; action: TurnAction; zombieTurn = false) =
|
|||
for facet, queue in queues:
|
||||
for action in queue: run(facet, action)
|
||||
|
||||
proc run*(`ref`: Ref; action: TurnAction) =
|
||||
## Convenience proc to run a `TurnAction` in the scope of a `Ref`.
|
||||
run(`ref`.relay, action)
|
||||
proc run*(cap: Cap; action: TurnAction) =
|
||||
## Convenience proc to run a `TurnAction` in the scope of a `Cap`.
|
||||
run(cap.relay, action)
|
||||
|
||||
proc addCallback*(fut: FutureBase; facet: Facet; act: TurnAction) =
|
||||
## Add a callback to a `Future` that will be called at a later `Turn`
|
||||
|
@ -592,13 +594,13 @@ proc freshen*(turn: var Turn, act: TurnAction) =
|
|||
assert(turn.queues.len == 0, "Attempt to freshen a non-stale Turn")
|
||||
run(turn.facet, act)
|
||||
|
||||
proc newRef*(relay: Facet; e: Entity): Ref =
|
||||
Ref(relay: relay, target: e)
|
||||
proc newCap*(relay: Facet; e: Entity): Cap =
|
||||
Cap(relay: relay, target: e)
|
||||
|
||||
proc newRef*(turn; e: Entity): Ref =
|
||||
Ref(relay: turn.facet, target: e)
|
||||
proc newCap*(turn; e: Entity): Cap =
|
||||
Cap(relay: turn.facet, target: e)
|
||||
|
||||
proc sync*(turn, refer: Ref, cb: proc(t: Turn) {.gcsafe.}) =
|
||||
proc sync*(turn, refer: Cap, cb: proc(t: Turn) {.gcsafe.}) =
|
||||
raiseAssert "not implemented"
|
||||
|
||||
proc future*(actor): Future[void] = actor.future
|
||||
|
|
|
@ -10,11 +10,11 @@ from syndicate/protocols/dataspace import Observe
|
|||
|
||||
export timer
|
||||
|
||||
type Observe = dataspace.Observe[Ref]
|
||||
type Observe = dataspace.Observe[Cap]
|
||||
|
||||
proc now: float64 = getTime().toUnixFloat()
|
||||
|
||||
proc spawnTimers*(turn: var Turn; ds: Ref): Actor {.discardable.} =
|
||||
proc spawnTimers*(turn: var Turn; ds: Cap): Actor {.discardable.} =
|
||||
## Spawn a timer actor.
|
||||
spawn("timer", turn) do (turn: var Turn):
|
||||
|
||||
|
@ -28,7 +28,7 @@ proc spawnTimers*(turn: var Turn; ds: Ref): Actor {.discardable.} =
|
|||
run(facet) do (turn: var Turn):
|
||||
discard publish(turn, ds, LaterThan(seconds: seconds))
|
||||
|
||||
template after*(turn: var Turn; ds: Ref; dur: Duration; act: untyped) =
|
||||
template after*(turn: var Turn; ds: Cap; dur: Duration; act: untyped) =
|
||||
## Execute `act` after some duration of time.
|
||||
let later = now() + dur.inMilliseconds.float64 * 1_000.0
|
||||
onPublish(turn, ds, ?LaterThan(seconds: later), act)
|
||||
|
|
|
@ -12,7 +12,7 @@ import hashlib/misc/blake2
|
|||
|
||||
import preserves
|
||||
import ./protocols/sturdy
|
||||
from ./actors import Ref
|
||||
from ./actors import Cap
|
||||
|
||||
export `$`
|
||||
|
||||
|
@ -26,9 +26,9 @@ proc mint*[T](key: openarray[byte]; oid: Preserve[T]): SturdyRef[T] =
|
|||
}.toDictionary,
|
||||
)
|
||||
|
||||
proc mint*(): SturdyRef[Ref] =
|
||||
proc mint*(): SturdyRef[Cap] =
|
||||
var key: array[16, byte]
|
||||
mint(key, toPreserve("syndicate", Ref))
|
||||
mint(key, toPreserve("syndicate", Cap))
|
||||
|
||||
proc attenuate*[T](r: SturdyRef[T]; caveats: seq[Caveat]): SturdyRef[T] =
|
||||
result = SturdyRef[T](
|
||||
|
|
|
@ -8,8 +8,8 @@ import ./actors, ./protocols/dataspace, ./skeletons
|
|||
from ./protocols/protocol import Handle
|
||||
|
||||
type
|
||||
Assertion = Preserve[Ref]
|
||||
Observe = dataspace.Observe[Ref]
|
||||
Assertion = Preserve[Cap]
|
||||
Observe = dataspace.Observe[Cap]
|
||||
Turn = actors.Turn
|
||||
|
||||
Dataspace {.final.} = ref object of Entity
|
||||
|
@ -34,10 +34,10 @@ method retract(ds: Dataspace; turn: var Turn; h: Handle) {.gcsafe.} =
|
|||
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()))
|
||||
proc newDataspace*(turn: var Turn): Cap =
|
||||
newCap(turn, Dataspace(index: initIndex()))
|
||||
|
||||
type BootProc = proc (ds: Ref; turn: var Turn) {.gcsafe.}
|
||||
type BootProc = proc (ds: Cap; turn: var Turn) {.gcsafe.}
|
||||
|
||||
proc bootDataspace*(name: string; bootProc: BootProc): Actor =
|
||||
bootActor(name) do (turn: var Turn):
|
||||
|
|
|
@ -8,7 +8,7 @@ import ./actors, ./patterns, ./protocols/dataspace
|
|||
from ./protocols/protocol import Handle
|
||||
|
||||
type
|
||||
Observe = dataspace.Observe[Ref]
|
||||
Observe = dataspace.Observe[Cap]
|
||||
Turn = actors.Turn
|
||||
|
||||
type
|
||||
|
@ -50,5 +50,5 @@ method retract(de: DuringEntity; turn: var Turn; h: Handle) =
|
|||
|
||||
proc during*(cb: DuringProc): DuringEntity = DuringEntity(cb: cb)
|
||||
|
||||
proc observe*(turn: var Turn; ds: Ref; pat: Pattern; e: Entity): Handle =
|
||||
publish(turn, ds, Observe(pattern: pat, observer: newRef(turn, e)))
|
||||
proc observe*(turn: var Turn; ds: Cap; pat: Pattern; e: Entity): Handle =
|
||||
publish(turn, ds, Observe(pattern: pat, observer: newCap(turn, e)))
|
||||
|
|
|
@ -3,43 +3,43 @@
|
|||
|
||||
import std/[hashes, tables]
|
||||
|
||||
from ./actors import Ref, hash
|
||||
from ./actors import Cap, hash
|
||||
from ./protocols/sturdy import Oid
|
||||
|
||||
proc hash(r: Ref): Hash = !$(r.relay.hash !& r.target.unsafeAddr.hash)
|
||||
proc hash(r: Cap): Hash = !$(r.relay.hash !& r.target.unsafeAddr.hash)
|
||||
|
||||
type
|
||||
Membrane* = object
|
||||
## Bidirectional mapping between `Oid` and `Ref` values.
|
||||
## Bidirectional mapping between `Oid` and `Cap` values.
|
||||
## https://synit.org/book/protocol.html#membranes
|
||||
byOid: Table[Oid, WireSymbol]
|
||||
byRef: Table[Ref, WireSymbol]
|
||||
byCap: Table[Cap, WireSymbol]
|
||||
|
||||
WireSymbol* = ref object
|
||||
oid: Oid
|
||||
`ref`: Ref
|
||||
cap: Cap
|
||||
count: int
|
||||
|
||||
proc oid*(sym: WireSymbol): Oid = sym.oid
|
||||
proc `ref`*(sym: WireSymbol): Ref = sym.ref
|
||||
proc cap*(sym: WireSymbol): Cap = sym.cap
|
||||
|
||||
proc grab*(mem: Membrane; key: Oid): WireSymbol =
|
||||
## Grab a `WireSymbol` from a `Membrane`.
|
||||
mem.byOid.getOrDefault(key)
|
||||
|
||||
proc grab*(mem: Membrane; key: Ref): WireSymbol =
|
||||
proc grab*(mem: Membrane; key: Cap): WireSymbol =
|
||||
## Grab a `WireSymbol` from a `Membrane`.
|
||||
mem.byRef.getOrDefault(key)
|
||||
mem.byCap.getOrDefault(key)
|
||||
|
||||
proc drop*(mem: var Membrane; sym: WireSymbol) =
|
||||
## Drop a `WireSymbol` from a `Membrane`.
|
||||
dec sym.count
|
||||
if sym.count < 1:
|
||||
mem.byOid.del sym.oid
|
||||
mem.byRef.del sym.`ref`
|
||||
mem.byCap.del sym.cap
|
||||
|
||||
proc newWireSymbol*(mem: var Membrane; o: Oid; r: Ref): WireSymbol =
|
||||
proc newWireSymbol*(mem: var Membrane; o: Oid; r: Cap): WireSymbol =
|
||||
## Allocate a `WireSymbol` at a `Membrane`.
|
||||
result = WireSymbol(oid: o, `ref`: r, count: 1)
|
||||
result = WireSymbol(oid: o, cap: r, count: 1)
|
||||
mem.byOid[result.oid] = result
|
||||
mem.byRef[result.`ref`] = result
|
||||
mem.byCap[result.cap] = result
|
||||
|
|
|
@ -5,20 +5,20 @@ import std/[algorithm, options, sequtils, tables, typetraits]
|
|||
|
||||
import preserves
|
||||
import ./protocols/dataspacePatterns
|
||||
from ./actors import Ref
|
||||
from ./actors import Cap
|
||||
|
||||
export dataspacePatterns.`$`, PatternKind, DCompoundKind, AnyAtomKind
|
||||
|
||||
type
|
||||
Value = Preserve[Ref]
|
||||
AnyAtom = dataspacePatterns.AnyAtom[Ref]
|
||||
DBind = dataspacePatterns.DBind[Ref]
|
||||
DCompound = dataspacePatterns.DCompound[Ref]
|
||||
DCompoundArr = dataspacePatterns.DCompoundArr[Ref]
|
||||
DCompoundDict = dataspacePatterns.DCompoundDict[Ref]
|
||||
DCompoundRec = dataspacePatterns.DCompoundRec[Ref]
|
||||
DLit = dataspacePatterns.DLit[Ref]
|
||||
Pattern* = dataspacePatterns.Pattern[Ref]
|
||||
Value = Preserve[Cap]
|
||||
AnyAtom = dataspacePatterns.AnyAtom[Cap]
|
||||
DBind = dataspacePatterns.DBind[Cap]
|
||||
DCompound = dataspacePatterns.DCompound[Cap]
|
||||
DCompoundArr = dataspacePatterns.DCompoundArr[Cap]
|
||||
DCompoundDict = dataspacePatterns.DCompoundDict[Cap]
|
||||
DCompoundRec = dataspacePatterns.DCompoundRec[Cap]
|
||||
DLit = dataspacePatterns.DLit[Cap]
|
||||
Pattern* = dataspacePatterns.Pattern[Cap]
|
||||
|
||||
iterator orderedEntries*(dict: DCompoundDict): (Value, Pattern) =
|
||||
## Iterate a `DCompoundDict` in Preserves order.
|
||||
|
@ -88,7 +88,7 @@ proc grab*[T](pr: Preserve[T]): Pattern =
|
|||
drop()
|
||||
else:
|
||||
DCompoundRec(
|
||||
label: cast[Preserve[Ref]](pr.label), # TODO: don't cast like this
|
||||
label: cast[Preserve[Cap]](pr.label), # TODO: don't cast like this
|
||||
fields: map[Preserve[T], Pattern](pr.fields, grab)).toPattern
|
||||
of pkSequence:
|
||||
DCompoundArr(items: map(pr.sequence, grab)).toPattern
|
||||
|
@ -96,7 +96,7 @@ proc grab*[T](pr: Preserve[T]): Pattern =
|
|||
raiseAssert "cannot construct a pattern over a set literal"
|
||||
of pkDictionary:
|
||||
var dict = DCompoundDict()
|
||||
for key, val in pr.pairs: dict.entries[cast[Preserve[Ref]](key)] = grab val
|
||||
for key, val in pr.pairs: dict.entries[cast[Preserve[Cap]](key)] = grab val
|
||||
dict.toPattern
|
||||
of pkEmbedded:
|
||||
# TODO: can patterns be constructed over embedded literals?
|
||||
|
@ -110,20 +110,20 @@ proc grab*[T](val: T): Pattern =
|
|||
$grab(true) == "<lit #t>"
|
||||
$grab(3.14) == "<lit 3.14>"
|
||||
$grab([0, 1, 2, 3]) == "<arr [<lit 0> <lit 1> <lit 2> <lit 3>]>"
|
||||
grab (toPreserve(val, Ref))
|
||||
grab (toPreserve(val, Cap))
|
||||
|
||||
proc patternOfType(typ: static typedesc; `bind`: static bool): Pattern =
|
||||
when typ is ref:
|
||||
patternOfType(pointerBase(typ), `bind`)
|
||||
elif typ.hasPreservesRecordPragma:
|
||||
var rec = DCompoundRec(label: typ.recordLabel.tosymbol(Ref))
|
||||
var rec = DCompoundRec(label: typ.recordLabel.tosymbol(Cap))
|
||||
for _, f in fieldPairs(default typ):
|
||||
add(rec.fields, patternOfType(typeof f, `bind`))
|
||||
result = rec.toPattern
|
||||
elif typ.hasPreservesDictionaryPragma:
|
||||
var dict = DCompoundDict()
|
||||
for key, val in fieldPairs(default typ):
|
||||
dict.entries[toSymbol(key, Ref)] = patternOfType(typeof val, `bind`)
|
||||
dict.entries[toSymbol(key, Cap)] = patternOfType(typeof val, `bind`)
|
||||
dict.toPattern
|
||||
elif typ is tuple:
|
||||
var arr = DCompoundArr()
|
||||
|
@ -191,7 +191,7 @@ proc grab*(typ: static typedesc; bindings: sink openArray[(int, Pattern)]): Patt
|
|||
when typ is ref:
|
||||
grab(pointerBase(typ), bindings)
|
||||
elif typ.hasPreservesRecordPragma:
|
||||
var rec = DCompoundRec(label: typ.recordLabel.tosymbol(Ref))
|
||||
var rec = DCompoundRec(label: typ.recordLabel.tosymbol(Cap))
|
||||
rec.fields.setLen(fieldCount typ)
|
||||
var i: int
|
||||
for _, f in fieldPairs(default typ):
|
||||
|
@ -269,7 +269,7 @@ proc inject*(pat: Pattern; bindings: openArray[(int, Pattern)]): Pattern =
|
|||
var offset = 0
|
||||
inject(pat, bindings, offset)
|
||||
|
||||
proc inject*(pat: Pattern; bindings: openArray[(Preserve[Ref], Pattern)]): Pattern =
|
||||
proc inject*(pat: Pattern; bindings: openArray[(Preserve[Cap], Pattern)]): Pattern =
|
||||
## Inject `bindings` into a dictionary pattern.
|
||||
assert pat.orKind == PatternKind.DCompound
|
||||
assert pat.dcompound.orKind == DCompoundKind.dict
|
||||
|
@ -277,12 +277,12 @@ proc inject*(pat: Pattern; bindings: openArray[(Preserve[Ref], Pattern)]): Patte
|
|||
for (key, val) in bindings:
|
||||
result.dcompound.dict.entries[key] = val
|
||||
|
||||
proc recordPattern*(label: Preserve[Ref], fields: varargs[Pattern]): Pattern =
|
||||
proc recordPattern*(label: Preserve[Cap], fields: varargs[Pattern]): Pattern =
|
||||
runnableExamples:
|
||||
from std/unittest import check
|
||||
import syndicate/actors, preserves
|
||||
check:
|
||||
$recordPattern("Says".toSymbol(Ref), grab(), grab()) ==
|
||||
$recordPattern("Says".toSymbol(Cap), grab(), grab()) ==
|
||||
"""<rec Says [<bind <_>> <bind <_>>]>"""
|
||||
DCompoundRec(label: label, fields: fields.toSeq).toPattern
|
||||
|
||||
|
@ -298,7 +298,7 @@ type
|
|||
func walk(result: var Analysis; path: var Path; p: Pattern)
|
||||
|
||||
func walk(result: var Analysis; path: var Path; key: int|Value; pat: Pattern) =
|
||||
path.add(key.toPreserve(Ref))
|
||||
path.add(key.toPreserve(Cap))
|
||||
walk(result, path, pat)
|
||||
discard path.pop
|
||||
|
||||
|
@ -318,7 +318,7 @@ func walk(result: var Analysis; path: var Path; p: Pattern) =
|
|||
of PatternKind.DDiscard: discard
|
||||
of PatternKind.DLit:
|
||||
result.constPaths.add(path)
|
||||
result.constValues.add(p.dlit.value.toPreserve(Ref))
|
||||
result.constValues.add(p.dlit.value.toPreserve(Cap))
|
||||
|
||||
func analyse*(p: Pattern): Analysis =
|
||||
var path: Path
|
||||
|
|
|
@ -19,7 +19,7 @@ type Oid = sturdy.Oid
|
|||
|
||||
type
|
||||
Value = Preserve[void]
|
||||
Assertion = Preserve[Ref]
|
||||
Assertion = Preserve[Cap]
|
||||
WireRef = sturdy.WireRef[void]
|
||||
|
||||
Turn = actors.Turn
|
||||
|
@ -42,7 +42,7 @@ type
|
|||
|
||||
SyncPeerEntity = ref object of Entity
|
||||
relay: Relay
|
||||
peer: Ref
|
||||
peer: Cap
|
||||
handleMap: Table[Handle, Handle]
|
||||
e: WireSymbol
|
||||
|
||||
|
@ -51,7 +51,7 @@ type
|
|||
label: string
|
||||
relay: Relay
|
||||
|
||||
proc releaseRefOut(r: Relay; e: WireSymbol) =
|
||||
proc releaseCapOut(r: Relay; e: WireSymbol) =
|
||||
r.exported.drop e
|
||||
|
||||
method publish(spe: SyncPeerEntity; t: var Turn; a: AssertionRef; h: Handle) =
|
||||
|
@ -64,22 +64,22 @@ method retract(se: SyncPeerEntity; t: var Turn; h: Handle) =
|
|||
|
||||
method message(se: SyncPeerEntity; t: var Turn; a: AssertionRef) =
|
||||
if not se.e.isNil:
|
||||
se.relay.releaseRefOut(se.e)
|
||||
se.relay.releaseCapOut(se.e)
|
||||
message(t, se.peer, a.value)
|
||||
|
||||
method sync(se: SyncPeerEntity; t: var Turn; peer: Ref) =
|
||||
method sync(se: SyncPeerEntity; t: var Turn; peer: Cap) =
|
||||
sync(t, se.peer, peer)
|
||||
|
||||
proc newSyncPeerEntity(r: Relay; p: Ref): SyncPeerEntity =
|
||||
proc newSyncPeerEntity(r: Relay; p: Cap): SyncPeerEntity =
|
||||
SyncPeerEntity(relay: r, peer: p)
|
||||
|
||||
proc rewriteRefOut(relay: Relay; `ref`: Ref; exported: var seq[WireSymbol]): WireRef =
|
||||
if `ref`.target of RelayEntity and `ref`.target.RelayEntity.relay == relay and `ref`.attenuation.len == 0:
|
||||
WireRef(orKind: WireRefKind.yours, yours: WireRefYours[void](oid: `ref`.target.oid))
|
||||
proc rewriteCapOut(relay: Relay; cap: Cap; exported: var seq[WireSymbol]): WireRef =
|
||||
if cap.target of RelayEntity and cap.target.RelayEntity.relay == relay and cap.attenuation.len == 0:
|
||||
WireRef(orKind: WireRefKind.yours, yours: WireRefYours[void](oid: cap.target.oid))
|
||||
else:
|
||||
var ws = grab(relay.exported, `ref`)
|
||||
var ws = grab(relay.exported, cap)
|
||||
if ws.isNil:
|
||||
ws = newWireSymbol(relay.exported, relay.nextLocalOid, `ref`)
|
||||
ws = newWireSymbol(relay.exported, relay.nextLocalOid, cap)
|
||||
inc relay.nextLocalOid
|
||||
exported.add ws
|
||||
WireRef(
|
||||
|
@ -89,8 +89,8 @@ proc rewriteRefOut(relay: Relay; `ref`: Ref; exported: var seq[WireSymbol]): Wir
|
|||
proc rewriteOut(relay: Relay; v: Assertion):
|
||||
tuple[rewritten: Value, exported: seq[WireSymbol]] {.gcsafe.} =
|
||||
var exported: seq[WireSymbol]
|
||||
result.rewritten = contract(v) do (r: Ref) -> Value:
|
||||
rewriteRefOut(relay, r, exported).toPreserve
|
||||
result.rewritten = contract(v) do (r: Cap) -> Value:
|
||||
rewriteCapOut(relay, r, exported).toPreserve
|
||||
result.exported = exported
|
||||
|
||||
proc register(relay: Relay; v: Assertion; h: Handle): tuple[rewritten: Value, exported: seq[WireSymbol]] =
|
||||
|
@ -100,7 +100,7 @@ proc register(relay: Relay; v: Assertion; h: Handle): tuple[rewritten: Value, ex
|
|||
proc deregister(relay: Relay; h: Handle) =
|
||||
var outbound: seq[WireSymbol]
|
||||
if relay.outboundAssertions.pop(h, outbound):
|
||||
for e in outbound: releaseRefOut(relay, e)
|
||||
for e in outbound: releaseCapOut(relay, e)
|
||||
|
||||
proc send(r: Relay; pkt: sink Packet): Future[void] =
|
||||
assert(not r.packetWriter.isNil, "missing packetWriter proc")
|
||||
|
@ -141,11 +141,11 @@ method message(re: RelayEntity; turn: var Turn; msg: AssertionRef) {.gcsafe.} =
|
|||
if len(exported) == 0:
|
||||
re.send Event(orKind: EventKind.Message, message: Message(body: value))
|
||||
|
||||
method sync(re: RelayEntity; turn: var Turn; peer: Ref) {.gcsafe.} =
|
||||
method sync(re: RelayEntity; turn: var Turn; peer: Cap) {.gcsafe.} =
|
||||
var
|
||||
peerEntity = newSyncPeerEntity(re.relay, peer)
|
||||
exported: seq[WireSymbol]
|
||||
discard rewriteRefOut(re.relay, turn.newRef(peerEntity), exported)
|
||||
discard rewriteCapOut(re.relay, turn.newCap(peerEntity), exported)
|
||||
# TODO: discard?
|
||||
peerEntity.e = exported[0]
|
||||
re.send Event(orKind: EventKind.Sync)
|
||||
|
@ -157,24 +157,24 @@ using
|
|||
relay: Relay
|
||||
facet: Facet
|
||||
|
||||
proc lookupLocal(relay; oid: Oid): Ref =
|
||||
proc lookupLocal(relay; oid: Oid): Cap =
|
||||
let sym = relay.exported.grab oid
|
||||
if sym.isNil: newInertRef()
|
||||
else: sym.`ref`
|
||||
if sym.isNil: newInertCap()
|
||||
else: sym.cap
|
||||
|
||||
proc isInert(r: Ref): bool =
|
||||
proc isInert(r: Cap): bool =
|
||||
r.target.isNil
|
||||
|
||||
proc rewriteRefIn(relay; facet; n: WireRef, imported: var seq[WireSymbol]): Ref =
|
||||
proc rewriteCapIn(relay; facet; n: WireRef, imported: var seq[WireSymbol]): Cap =
|
||||
case n.orKind
|
||||
of WireRefKind.mine:
|
||||
var e = relay.imported.grab(n.mine.oid)
|
||||
if e.isNil: e = newWireSymbol(
|
||||
relay.imported,
|
||||
n.mine.oid,
|
||||
newRef(facet, newRelayEntity("rewriteRefIn", relay, n.mine.oid)))
|
||||
newCap(facet, newRelayEntity("rewriteCapIn", relay, n.mine.oid)))
|
||||
imported.add e
|
||||
result = e.`ref`
|
||||
result = e.cap
|
||||
of WireRefKind.yours:
|
||||
let r = relay.lookupLocal(n.yours.oid)
|
||||
if n.yours.attenuation.len == 0 or r.isInert: result = r
|
||||
|
@ -187,16 +187,16 @@ proc rewriteIn(relay; facet; v: Value):
|
|||
var wr: WireRef
|
||||
if not fromPreserve(wr, pr):
|
||||
raiseAssert "expansion of embedded value failed"
|
||||
rewriteRefIn(relay, facet, wr, imported).toPreserve(Ref)
|
||||
rewriteCapIn(relay, facet, wr, imported).toPreserve(Cap)
|
||||
result.imported = imported
|
||||
|
||||
proc close(r: Relay) = discard
|
||||
|
||||
proc dispatch*(relay: Relay; turn: var Turn; `ref`: Ref; event: Event) {.gcsafe.} =
|
||||
proc dispatch*(relay: Relay; turn: var Turn; cap: Cap; event: Event) {.gcsafe.} =
|
||||
case event.orKind
|
||||
of EventKind.Assert:
|
||||
let (a, imported) = rewriteIn(relay, turn.facet, event.assert.assertion)
|
||||
relay.inboundAssertions[event.assert.handle] = (publish(turn, `ref`, a), imported,)
|
||||
relay.inboundAssertions[event.assert.handle] = (publish(turn, cap, a), imported,)
|
||||
|
||||
of EventKind.Retract:
|
||||
let remoteHandle = event.retract.handle
|
||||
|
@ -208,14 +208,14 @@ proc dispatch*(relay: Relay; turn: var Turn; `ref`: Ref; event: Event) {.gcsafe.
|
|||
of EventKind.Message:
|
||||
let (a, imported) = rewriteIn(relay, turn.facet, event.message.body)
|
||||
assert imported.len == 0, "Cannot receive transient reference"
|
||||
turn.message(`ref`, a)
|
||||
turn.message(cap, a)
|
||||
|
||||
of EventKind.Sync:
|
||||
discard # TODO
|
||||
#[
|
||||
var imported: seq[WireSymbol]
|
||||
let k = relay.rewriteRefIn(turn, evenr.sync.peer, imported)
|
||||
turn.sync(`ref`) do (turn: var Turn):
|
||||
let k = relay.rewriteCapIn(turn, evenr.sync.peer, imported)
|
||||
turn.sync(cap) do (turn: var Turn):
|
||||
turn.message(k, true)
|
||||
for e in imported: relay.imported.del e
|
||||
]#
|
||||
|
@ -233,7 +233,7 @@ proc dispatch*(relay: Relay; v: Value) {.gcsafe.} =
|
|||
if not r.isInert:
|
||||
dispatch(relay, t, r, te.event)
|
||||
else:
|
||||
stderr.writeLine("discarding event for unknown Ref; ", te.event)
|
||||
stderr.writeLine("discarding event for unknown Cap; ", te.event)
|
||||
of PacketKind.Error:
|
||||
# https://synit.org/book/protocol.html#error-packets
|
||||
when defined(posix):
|
||||
|
@ -252,7 +252,7 @@ type
|
|||
untrusted*: bool
|
||||
RelayActorOptions* = object of RelayOptions
|
||||
initialOid*: Option[Oid]
|
||||
initialRef*: Ref
|
||||
initialCap*: Cap
|
||||
nextLocalOid*: Option[Oid]
|
||||
|
||||
proc newRelay(turn: var Turn; opts: RelayOptions; setup: RelaySetup): Relay =
|
||||
|
@ -263,19 +263,19 @@ proc newRelay(turn: var Turn; opts: RelayOptions; setup: RelaySetup): Relay =
|
|||
discard result.facet.preventInertCheck()
|
||||
setup(turn, result)
|
||||
|
||||
proc spawnRelay*(name: string; turn: var Turn; opts: RelayActorOptions; setup: RelaySetup): Future[Ref] =
|
||||
var fut = newFuture[Ref]"spawnRelay"
|
||||
proc spawnRelay*(name: string; turn: var Turn; opts: RelayActorOptions; setup: RelaySetup): Future[Cap] =
|
||||
var fut = newFuture[Cap]"spawnRelay"
|
||||
discard spawn(name, turn) do (turn: var Turn):
|
||||
let relay = newRelay(turn, opts, setup)
|
||||
if not opts.initialRef.isNil:
|
||||
if not opts.initialCap.isNil:
|
||||
var exported: seq[WireSymbol]
|
||||
discard rewriteRefOut(relay, opts.initialRef, exported)
|
||||
discard rewriteCapOut(relay, opts.initialCap, exported)
|
||||
if opts.initialOid.isSome:
|
||||
var imported: seq[WireSymbol]
|
||||
var wr = WireRef(
|
||||
orKind: WireRefKind.mine,
|
||||
mine: WireRefMine(oid: opts.initialOid.get))
|
||||
fut.complete rewriteRefIn(relay, turn.facet, wr, imported)
|
||||
fut.complete rewriteCapIn(relay, turn.facet, wr, imported)
|
||||
else:
|
||||
fut.complete(nil)
|
||||
opts.nextLocalOid.map do (oid: Oid):
|
||||
|
@ -295,23 +295,23 @@ type ShutdownEntity* = ref object of Entity
|
|||
method retract(e: ShutdownEntity; turn: var Turn; h: Handle) =
|
||||
stopActor(turn)
|
||||
|
||||
type ConnectProc* = proc (turn: var Turn; ds: Ref) {.gcsafe.}
|
||||
type ConnectProc* = proc (turn: var Turn; ds: Cap) {.gcsafe.}
|
||||
|
||||
export Tcp
|
||||
|
||||
when defined(posix):
|
||||
export Unix
|
||||
|
||||
proc connect*(turn: var Turn; socket: AsyncSocket; step: Preserve[Ref]; bootProc: ConnectProc) =
|
||||
proc connect*(turn: var Turn; socket: AsyncSocket; step: Preserve[Cap]; bootProc: ConnectProc) =
|
||||
## Relay a dataspace over an open `AsyncSocket`.
|
||||
## *`bootProc` may be called multiple times for multiple remote gatekeepers.*
|
||||
proc socketWriter(packet: sink Packet): Future[void] =
|
||||
socket.send(cast[string](encode(packet)))
|
||||
const recvSize = 0x2000
|
||||
var shutdownRef: Ref
|
||||
var shutdownCap: Cap
|
||||
let
|
||||
reenable = turn.facet.preventInertCheck()
|
||||
connectionClosedRef = newRef(turn, ShutdownEntity())
|
||||
connectionClosedCap = newCap(turn, ShutdownEntity())
|
||||
fut = newFuture[void]"connect"
|
||||
discard bootActor("socket") do (turn: var Turn):
|
||||
var ops = RelayActorOptions(
|
||||
|
@ -336,18 +336,18 @@ when defined(posix):
|
|||
socket.recv(recvSize).addCallback(recvCb)
|
||||
socket.recv(recvSize).addCallback(recvCb)
|
||||
turn.facet.actor.atExit do (turn: var Turn): close(socket)
|
||||
discard publish(turn, connectionClosedRef, true)
|
||||
shutdownRef = newRef(turn, ShutdownEntity())
|
||||
discard publish(turn, connectionClosedCap, true)
|
||||
shutdownCap = newCap(turn, ShutdownEntity())
|
||||
addCallback(refFut) do ():
|
||||
let gatekeeper = read refFut
|
||||
run(gatekeeper.relay) do (turn: var Turn):
|
||||
reenable()
|
||||
discard publish(turn, shutdownRef, true)
|
||||
discard publish(turn, shutdownCap, true)
|
||||
proc duringCallback(turn: var Turn; a: Assertion; h: Handle): TurnAction =
|
||||
let facet = inFacet(turn) do (turn: var Turn):
|
||||
var
|
||||
accepted: ResolvedAccepted[Ref]
|
||||
rejected: Rejected[Ref]
|
||||
accepted: ResolvedAccepted[Cap]
|
||||
rejected: Rejected[Cap]
|
||||
if fromPreserve(accepted, a):
|
||||
bootProc(turn, accepted.responderSession)
|
||||
elif fromPreserve(rejected, a):
|
||||
|
@ -357,14 +357,14 @@ when defined(posix):
|
|||
proc action(turn: var Turn) =
|
||||
stop(turn, facet)
|
||||
result = action
|
||||
discard publish(turn, gatekeeper, Resolve[Ref](
|
||||
discard publish(turn, gatekeeper, Resolve[Cap](
|
||||
step: step,
|
||||
observer: newRef(turn, during(duringCallback)),
|
||||
observer: newCap(turn, during(duringCallback)),
|
||||
))
|
||||
fut.complete()
|
||||
asyncCheck(turn, fut)
|
||||
|
||||
proc connect*(turn: var Turn; transport: Tcp; step: Preserve[Ref]; bootProc: ConnectProc) =
|
||||
proc connect*(turn: var Turn; transport: Tcp; step: Preserve[Cap]; bootProc: ConnectProc) =
|
||||
## Relay a dataspace over TCP.
|
||||
## *`bootProc` may be called multiple times for multiple remote gatekeepers.*
|
||||
let socket = newAsyncSocket(
|
||||
|
@ -376,7 +376,7 @@ when defined(posix):
|
|||
addCallback(fut, turn) do (turn: var Turn):
|
||||
connect(turn, socket, step, bootProc)
|
||||
|
||||
proc connect*(turn: var Turn; transport: Unix; step: Preserve[Ref]; bootProc: ConnectProc) =
|
||||
proc connect*(turn: var Turn; transport: Unix; step: Preserve[Cap]; bootProc: ConnectProc) =
|
||||
## Relay a dataspace over a UNIX socket.
|
||||
## *`bootProc` may be called multiple times for multiple remote gatekeepers.*
|
||||
let socket = newAsyncSocket(
|
||||
|
@ -392,7 +392,7 @@ when defined(posix):
|
|||
|
||||
const stdinReadSize = 128
|
||||
|
||||
proc connectStdio*(ds: Ref; turn: var Turn) =
|
||||
proc connectStdio*(ds: Cap; turn: var Turn) =
|
||||
## Connect to an external dataspace over stdin and stdout.
|
||||
proc stdoutWriter(packet: sink Packet): Future[void] {.async.} =
|
||||
var buf = encode(packet)
|
||||
|
@ -400,7 +400,7 @@ when defined(posix):
|
|||
flushFile(stdout)
|
||||
var opts = RelayActorOptions(
|
||||
packetWriter: stdoutWriter,
|
||||
initialRef: ds,
|
||||
initialCap: ds,
|
||||
initialOid: 0.Oid.some)
|
||||
asyncCheck spawnRelay("stdio", turn, opts) do (turn: var Turn; relay: Relay):
|
||||
let
|
||||
|
|
|
@ -9,9 +9,9 @@ import ./actors, ./bags, ./patterns
|
|||
import ./protocols/dataspacePatterns
|
||||
|
||||
type
|
||||
DCompound = dataspacePatterns.DCompound[Ref]
|
||||
Pattern = dataspacePatterns.Pattern[Ref]
|
||||
Value = Preserve[Ref]
|
||||
DCompound = dataspacePatterns.DCompound[Cap]
|
||||
Pattern = dataspacePatterns.Pattern[Cap]
|
||||
Value = Preserve[Cap]
|
||||
Path = seq[Value]
|
||||
ClassKind = enum classNone, classRecord, classSequence, classDictionary
|
||||
Class = object
|
||||
|
@ -61,7 +61,7 @@ type
|
|||
|
||||
ObserverGroup = ref object # Endpoints
|
||||
cachedCaptures: Bag[Captures]
|
||||
observers: Table[Ref, TableRef[Captures, Handle]]
|
||||
observers: Table[Cap, TableRef[Captures, Handle]]
|
||||
|
||||
Leaf = ref object
|
||||
cache: AssertionCache
|
||||
|
@ -140,7 +140,6 @@ proc modify(node: Node; turn: var Turn; outerValue: Value; event: EventKind;
|
|||
|
||||
proc walk(cont: Continuation; turn: var Turn) =
|
||||
modCont(cont, outerValue)
|
||||
assert not cont.isEmpty()
|
||||
for constPaths, constValMap in cont.leafMap.pairs:
|
||||
let constVals = projectPaths(outerValue, constPaths)
|
||||
if constVals.isSome:
|
||||
|
@ -180,7 +179,7 @@ proc modify(node: Node; turn: var Turn; outerValue: Value; event: EventKind;
|
|||
if event == removedEvent and nextNode.isEmpty:
|
||||
table.del(nextClass)
|
||||
|
||||
walk(node, turn, @[@[outerValue].toPreserve(Ref)])
|
||||
walk(node, turn, @[@[outerValue].toPreserve(Cap)])
|
||||
|
||||
proc getOrNew[A, B, C](t: var Table[A, TableRef[B, C]], k: A): TableRef[B, C] =
|
||||
result = t.getOrDefault(k)
|
||||
|
@ -192,10 +191,10 @@ iterator pairs(dc: DCompound): (Value, Pattern) =
|
|||
case dc.orKind
|
||||
of DCompoundKind.rec:
|
||||
for i, p in dc.rec.fields:
|
||||
yield (toPreserve(i, Ref), p,)
|
||||
yield (toPreserve(i, Cap), p,)
|
||||
of DCompoundKind.arr:
|
||||
for i, p in dc.arr.items:
|
||||
yield (toPreserve(i, Ref), p,)
|
||||
yield (toPreserve(i, Cap), p,)
|
||||
of DCompoundKind.dict:
|
||||
for pair in dc.dict.entries.pairs:
|
||||
yield pair
|
||||
|
@ -229,7 +228,7 @@ proc extendWalk(node: Node; popCount: Natural; stepIndex: Value; pat: Pattern; p
|
|||
|
||||
proc extend(node: var Node; pat: Pattern): Continuation =
|
||||
var path: Path
|
||||
extendWalk(node, 0, toPreserve(0, Ref), pat, path).nextNode.continuation
|
||||
extendWalk(node, 0, toPreserve(0, Cap), pat, path).nextNode.continuation
|
||||
|
||||
type
|
||||
Index* = object
|
||||
|
@ -250,7 +249,7 @@ proc getEndpoints(leaf: Leaf; capturePaths: Paths): ObserverGroup =
|
|||
if captures.isSome:
|
||||
discard result.cachedCaptures.change(get captures, +1)
|
||||
|
||||
proc add*(index: var Index; turn: var Turn; pattern: Pattern; observer: Ref) =
|
||||
proc add*(index: var Index; turn: var Turn; pattern: Pattern; observer: Cap) =
|
||||
let
|
||||
cont = index.root.extend(pattern)
|
||||
analysis = analyse pattern
|
||||
|
@ -263,7 +262,7 @@ proc add*(index: var Index; turn: var Turn; pattern: Pattern; observer: Ref) =
|
|||
captureMap[capture] = publish(turn, observer, capture)
|
||||
endpoints.observers[observer] = captureMap
|
||||
|
||||
proc remove*(index: var Index; turn: var Turn; pattern: Pattern; observer: Ref) =
|
||||
proc remove*(index: var Index; turn: var Turn; pattern: Pattern; observer: Cap) =
|
||||
let
|
||||
cont = index.root.extend(pattern)
|
||||
analysis = analyse pattern
|
||||
|
@ -295,7 +294,7 @@ proc adjustAssertion(index: var Index; turn: var Turn; outerValue: Value; delta:
|
|||
let change = group.cachedCaptures.change(vs, +1)
|
||||
if change == cdAbsentToPresent:
|
||||
for (observer, captureMap) in group.observers.pairs:
|
||||
captureMap[vs] = publish(turn, observer, vs.toPreserve(Ref))
|
||||
captureMap[vs] = publish(turn, observer, vs.toPreserve(Cap))
|
||||
# TODO: this handle is coming from the facet?
|
||||
modify(index.root, turn, outerValue, addedEvent, modContinuation, modLeaf, modObserver)
|
||||
of cdPresentToAbsent:
|
||||
|
|
|
@ -10,7 +10,7 @@ type
|
|||
Says {.preservesRecord: "Says".} = object
|
||||
who, what: string
|
||||
|
||||
proc readStdin(facet: Facet; ds: Ref; username: string) =
|
||||
proc readStdin(facet: Facet; ds: Cap; username: string) =
|
||||
let file = openAsync("/dev/stdin")
|
||||
onStop(facet) do (turn: var Turn): close(file)
|
||||
close(stdin)
|
||||
|
@ -22,7 +22,7 @@ proc readStdin(facet: Facet; ds: Ref; username: string) =
|
|||
readLine()
|
||||
readLine()
|
||||
|
||||
proc chat(turn: var Turn; ds: Ref; username: string) =
|
||||
proc chat(turn: var Turn; ds: Cap; username: string) =
|
||||
during(turn, ds, ?Present) do (who: string):
|
||||
echo who, " joined"
|
||||
do:
|
||||
|
@ -37,7 +37,7 @@ proc chat(turn: var Turn; ds: Ref; username: string) =
|
|||
proc main =
|
||||
var
|
||||
transport: Preserve[void]
|
||||
cap: Preserve[Ref]
|
||||
cap: Preserve[Cap]
|
||||
username = getEnv("USER")
|
||||
calledWithArguments = false
|
||||
for kind, key, val in getopt():
|
||||
|
@ -47,20 +47,20 @@ proc main =
|
|||
of "address", "transport":
|
||||
transport = parsePreserves(val)
|
||||
of "cap", "sturdy":
|
||||
cap = parsePreserves(val, Ref)
|
||||
cap = parsePreserves(val, Cap)
|
||||
of "user", "username":
|
||||
username = val
|
||||
|
||||
if calledWithArguments:
|
||||
runActor("chat") do (root: Ref; turn: var Turn):
|
||||
runActor("chat") do (root: Cap; turn: var Turn):
|
||||
var
|
||||
unixAddr: transportAddress.Unix
|
||||
tcpAddr: transportAddress.Tcp
|
||||
if fromPreserve(unixAddr, transport):
|
||||
connect(turn, unixAddr, cap) do (turn: var Turn; ds: Ref):
|
||||
connect(turn, unixAddr, cap) do (turn: var Turn; ds: Cap):
|
||||
chat(turn, ds, username)
|
||||
elif fromPreserve(tcpAddr, transport):
|
||||
connect(turn, tcpAddr, cap) do (turn: var Turn; ds: Ref):
|
||||
connect(turn, tcpAddr, cap) do (turn: var Turn; ds: Cap):
|
||||
chat(turn, ds, username)
|
||||
|
||||
main()
|
||||
|
|
|
@ -5,7 +5,7 @@ import std/unittest
|
|||
|
||||
import preserves, syndicate
|
||||
from syndicate/protocols/dataspace import Observe
|
||||
type Observe = dataspace.Observe[Ref]
|
||||
type Observe = dataspace.Observe[Cap]
|
||||
|
||||
import ./test_schema
|
||||
|
||||
|
@ -16,9 +16,9 @@ test "patterns":
|
|||
|
||||
let
|
||||
value = @["alles", "in", "ordnung"]
|
||||
observer = toPreserve(Observe(pattern: inject(?Foo, { 0: ?value })), Ref)
|
||||
have = capture(observerPat, observer).toPreserve(Ref).unpackLiterals
|
||||
want = [value.toPreserve(Ref)].toPreserve(Ref)
|
||||
observer = toPreserve(Observe(pattern: inject(?Foo, { 0: ?value })), Cap)
|
||||
have = capture(observerPat, observer).toPreserve(Cap).unpackLiterals
|
||||
want = [value.toPreserve(Cap)].toPreserve(Cap)
|
||||
check(have == want)
|
||||
|
||||
type Record {.preservesDictionary.} = object
|
||||
|
@ -27,10 +27,10 @@ type Record {.preservesDictionary.} = object
|
|||
test "dictionaries":
|
||||
let pat = ?Record
|
||||
echo pat
|
||||
var source = initDictionary(Ref)
|
||||
source["b".toSymbol(Ref)] = 2.toPreserve(Ref)
|
||||
source["c".toSymbol(Ref)] = 3.toPreserve(Ref)
|
||||
source["a".toSymbol(Ref)] = 1.toPreserve(Ref)
|
||||
var source = initDictionary(Cap)
|
||||
source["b".toSymbol(Cap)] = 2.toPreserve(Cap)
|
||||
source["c".toSymbol(Cap)] = 3.toPreserve(Cap)
|
||||
source["a".toSymbol(Cap)] = 1.toPreserve(Cap)
|
||||
|
||||
let values = capture(pat, source)
|
||||
check $values == "@[1, 2, 3]"
|
||||
|
|
|
@ -6,7 +6,7 @@ import syndicate, syndicate/actors/timers
|
|||
|
||||
proc now: float64 = getTime().toUnixFloat()
|
||||
|
||||
runActor("test_timers") do (ds: Ref; turn: var Turn):
|
||||
runActor("test_timers") do (ds: Cap; turn: var Turn):
|
||||
onPublish(turn, ds, ?LaterThan(seconds: now()+1.0)) do:
|
||||
stderr.writeLine "slept one second once"
|
||||
onPublish(turn, ds, ?LaterThan(seconds: now()+1.0)) do:
|
||||
|
|
Loading…
Reference in New Issue