Rewrite timers

This commit is contained in:
Emery Hemingway 2023-07-13 15:07:04 +01:00
parent 9614955320
commit ca12c1ae03
4 changed files with 73 additions and 23 deletions

View File

@ -0,0 +1,3 @@
include_rules
NIM_FLAGS += --path:$(TUP_CWD)/../..
: foreach *.nim |> !nim_check |>

View File

@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[asyncdispatch, monotimes, times]
import preserves
import syndicate, syndicate/actors
import ../protocols/timer
from syndicate/protocols/dataspace import Observe
export timer
type Observe = dataspace.Observe[Ref]
proc now: float64 = getTime().toUnixFloat()
proc spawnTimers*(turn: var Turn; ds: Ref) =
## Spawn a timer actor.
spawn("timer", turn) do (turn: var Turn):
during(turn, ds, ?Observe(pattern: !LaterThan) ?? {0: grabLit()}) do (seconds: float64):
let period = seconds - now()
if period < 0.001:
discard publish(turn, ds, LaterThan(seconds: seconds))
else:
let facet = turn.facet
addTimer(int(period * 1_000), oneshot = true) do (fd: AsyncFD) -> bool:
run(facet) do (turn: var Turn):
discard publish(turn, ds, LaterThan(seconds: seconds))
template after*(turn: var Turn; ds: Ref; 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)

View File

@ -1,23 +0,0 @@
# SPDX-FileCopyrightText: 2021 ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[asyncdispatch, monotimes, times]
import preserves, preserves/records
import syndicate, syndicate/assertions
import ../../syndicate/protocols/schemas/timer
syndicate timerDriver:
spawn "timer":
during(observe(laterThan(?msecs))) do (msecs: float64):
let
now = getTime().toUnixFloat() * 1_000.0
period = msecs - now
if period > 0:
getCurrentFacet().beginExternalTask()
addTimer(period.int, oneshot = true) do (fd: AsyncFD) -> bool:
react: publish: laterThan(deadline)
getCurrentFacet().endExternalTask()
true
else:
react: publish: prsTimeLaterThan(deadline)

36
tests/test_timers.nim Normal file
View File

@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[asyncdispatch, os, times]
import preserves, syndicate, syndicate/actors/timers
proc now: float64 = getTime().toUnixFloat()
proc testTimers(turn: var Turn; ds: Ref) =
onPublish(turn, ds, ?LaterThan(seconds: now()+1.0)) do:
stderr.writeLine "slept one second once"
onPublish(turn, ds, ?LaterThan(seconds: now()+1.0)) do:
stderr.writeLine "slept one second twice"
onPublish(turn, ds, ?LaterThan(seconds: now()+1.0)) do:
stderr.writeLine "slept one second thrice"
quit()
spawnTimers(turn, ds)
type Args {.preservesDictionary.} = object
dataspace: Ref
proc asInferior: bool =
commandLineParams() == @["--inferior"]
if asInferior():
stderr.writeLine "connect stdio"
runActor("test_timers") do (root: Ref; turn: var Turn):
connectStdio(root, turn)
during(turn, root, ?Args) do (ds: Ref):
testTimers(turn, ds)
else:
stderr.writeLine "use local dataspace"
discard bootDataspace("test_timers") do (ds: Ref; turn: var Turn):
testTimers(turn, ds)
for i in 0..10: poll()