- monitor(watched, observer, msg): registration lives on the watched actor's home thread (kind-7 envelope cross-shard); actor_die walks the list; already-dead fires NOW; the notice msg moves; a full observer's notice drops with a stderr line (no fiber to trap) - time.after(ms, addr, msg): per-shard timer list riding the deadline machinery (uring tick min + epoll timeout both include timers; fired from the same sweep); ms <= 0 delivers now; NO cancel — the generation-counter idiom is pinned by run/timer-generation - runtime_notify: one runtime-sourced delivery path (notices, timers) — reserve-or-drop, cross-shard via kind-0 envelopes - compiler: monitor typed as a bespoke free fn (notice typed against the OBSERVER's mailbox — the three-argument deviation, disclosed); time.after as a stdlib row whose msg arg is EXEMPT from the module- call fresh-arg drop (it moves — the double-own bug the timer fixture caught); owner move slots for both - corpus: run/monitor-death (trap-death + already-dead notices), run/timer-delivery (armed + immediate), run/timer-generation - teardown drops undelivered notices and unfired timers; battery 13/13 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
23 lines
472 B
Text
23 lines
472 B
Text
use time
|
|
|
|
-- iteration 24 T5: a timer is a MESSAGE. time.after arms a one-shot on
|
|
-- this shard; the target receives it like any send. ms <= 0 delivers now.
|
|
class Tick {
|
|
tag: Text
|
|
}
|
|
|
|
class Sink {
|
|
pad: Int
|
|
fn receive(msg: Tick) {
|
|
print("tick: ${msg.tag}");
|
|
}
|
|
}
|
|
|
|
fn main() -> Int {
|
|
let a: actor Tick = spawn Sink { pad: 0 };
|
|
time.after(30, a, Tick { tag: "armed" });
|
|
time.after(0, a, Tick { tag: "now" });
|
|
time.sleep(150);
|
|
print("done");
|
|
return 0;
|
|
}
|