2023-11-08 10:50:30 +00:00
|
|
|
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
|
|
|
# SPDX-License-Identifier: Unlicense
|
|
|
|
|
|
|
|
import std/times
|
|
|
|
import preserves, syndicate,
|
2024-04-05 13:18:47 +00:00
|
|
|
syndicate/durings,
|
|
|
|
syndicate/drivers/timers
|
2023-11-08 10:50:30 +00:00
|
|
|
|
2024-01-08 19:42:46 +00:00
|
|
|
import ../schema/config
|
2023-11-08 10:50:30 +00:00
|
|
|
|
|
|
|
proc afterTimeout(n: float64): LaterThan =
|
|
|
|
## Get a `LaterThan` record for `n` seconds in the future.
|
|
|
|
result.seconds = getTime().toUnixFloat() + n
|
|
|
|
|
|
|
|
type CacheEntity {.final.} = ref object of Entity
|
|
|
|
timeouts, target: Cap
|
|
|
|
# dataspaces for observing timeouts and publishing values
|
|
|
|
pattern: Pattern
|
|
|
|
lifetime: float64
|
|
|
|
|
|
|
|
method publish(cache: CacheEntity; turn: var Turn; ass: AssertionRef; h: Handle) =
|
|
|
|
## Re-assert pattern captures in a sub-facet.
|
|
|
|
discard inFacet(turn) do (turn: var Turn):
|
|
|
|
# TODO: a seperate facet for every assertion, too much?
|
|
|
|
var ass = depattern(cache.pattern, ass.value.sequence)
|
|
|
|
# Build an assertion with what he have of the pattern and capture.
|
|
|
|
discard publish(turn, cache.target, ass)
|
|
|
|
let timeout = afterTimeout(cache.lifetime)
|
|
|
|
onPublish(turn, cache.timeouts, ?timeout) do:
|
|
|
|
stop(turn) # end this facet
|
|
|
|
|
|
|
|
proc isObserve(pat: Pattern): bool =
|
|
|
|
pat.orKind == PatternKind.DCompound and
|
|
|
|
pat.dcompound.orKind == DCompoundKind.rec and
|
|
|
|
pat.dcompound.rec.label.isSymbol"Observe"
|
|
|
|
|
2023-12-25 23:11:54 +00:00
|
|
|
proc spawnCacheActor*(turn: var Turn; root: Cap): Actor =
|
2024-04-05 13:18:47 +00:00
|
|
|
spawnActor(turn, "cache_actor") do (turn: var Turn):
|
2024-01-08 19:42:46 +00:00
|
|
|
during(turn, root, ?:CacheArguments) do (ds: Cap, lifetime: float64):
|
2023-12-25 23:11:54 +00:00
|
|
|
onPublish(turn, ds, ?:Observe) do (pat: Pattern, obs: Cap):
|
|
|
|
var cache: CacheEntity
|
|
|
|
if obs.relay != turn.facet and not(pat.isObserve):
|
|
|
|
# Watch pattern if the observer is not us
|
|
|
|
# and if the pattern isn't a recursive observe
|
|
|
|
cache = CacheEntity(
|
|
|
|
timeouts: root,
|
|
|
|
target: ds,
|
|
|
|
pattern: pat,
|
|
|
|
lifetime: lifetime,
|
|
|
|
)
|
|
|
|
discard observe(turn, ds, pat, cache)
|
|
|
|
|
|
|
|
when isMainModule:
|
2024-04-05 13:18:47 +00:00
|
|
|
import syndicate/relays
|
|
|
|
runActor("main") do (turn: var Turn):
|
|
|
|
resolveEnvironment(turn) do (turn: var Turn; ds: Cap):
|
|
|
|
discard spawnTimerDriver(turn, ds)
|
|
|
|
discard spawnCacheActor(turn, ds)
|