Sleeping parks one fiber
Clock.sleep(duration) parks the current fiber until the provided Clock reaches the deadline. Other fibers keep running; the host thread waits only when every fiber is parked.
Clock.virtual(start) is the deterministic provider for tests. Its time stands still while any fiber can run, then jumps straight to the earliest pending deadline, so a test observes exact elapsed time without waiting.
Timers run on the native scheduler. The browser runtime does not implement Clock yet.
type TimerProbe = {
mut events: Vector(String);
}
let recordrecord: fn(probe: Book.Concurrency.Timers.TimerProbe @ global, event: String @ global) -> Unit = fn(probeprobe: Book.Concurrency.Timers.TimerProbe, eventevent: String) {
probe.events := Vector.pushpush: pure fn!('a)(items: Vector(String), item: String) -> Vector(String)(probeprobe: Book.Concurrency.Timers.TimerProbe.eventsevents: Vector(String), eventevent: String);
};
let epochepoch: Instant = must Instant.parse_rfc3339parse_rfc3339: pure fn(string: String) -> Instant, exn [ :parse(String) ]("2026-01-01T00:00:00Z""2026-01-01T00:00:00Z": String);
Sleepers Wake In Deadline Order
let probeprobe: Book.Concurrency.Timers.TimerProbe: TimerProbe @ global = TimerProbe { events = []; };
provide { Clock = Clock.virtualvirtual: pure fn!(start: Instant) -> Service.Provider(Clock)(epochepoch: Instant); } {
let startstart: Clock.MonotonicInstant = Clock.markmark: fn!() -> Clock.MonotonicInstant();
let slowslow: Async.Task(Unit) = spawn {
Clock.sleepsleep: fn!(duration: Duration) -> Unit, eff Clock(Duration.secondsseconds: pure fn!(value: Int) -> Duration(22: Int));
recordrecord: fn(probe: Book.Concurrency.Timers.TimerProbe @ global, event: String @ global) -> Unit(probeprobe: Book.Concurrency.Timers.TimerProbe, "slow""slow": String);
};
let fastfast: Async.Task(Unit) = spawn {
Clock.sleepsleep: fn!(duration: Duration) -> Unit, eff Clock(Duration.secondsseconds: pure fn!(value: Int) -> Duration(11: Int));
recordrecord: fn(probe: Book.Concurrency.Timers.TimerProbe @ global, event: String @ global) -> Unit(probeprobe: Book.Concurrency.Timers.TimerProbe, "fast""fast": String);
};
recordrecord: fn(probe: Book.Concurrency.Timers.TimerProbe @ global, event: String @ global) -> Unit(probeprobe: Book.Concurrency.Timers.TimerProbe, "running""running": String);
await slowslow: Async.Task(Unit);
await fastfast: Async.Task(Unit);
expect ✓Clock.elapsed_sinceelapsed_since: fn!(mark: Clock.MonotonicInstant) -> Duration(startstart: Clock.MonotonicInstant) == Duration.secondsseconds: pure fn!(value: Int) -> Duration(22: Int);
expect ✓Clock.nownow: fn!() -> Instant() == must Instant.addadd: pure fn(instant: Instant, duration: Duration) -> Instant, exn [ :overflow ](epochepoch: Instant, Duration.secondsseconds: pure fn!(value: Int) -> Duration(22: Int));
};
expect ✓probeprobe: Book.Concurrency.Timers.TimerProbe.eventsevents: Vector(String) == ["running""running": String, "fast""fast": String, "slow""slow": String];A zero or negative duration still parks the fiber: every other runnable fiber gets a turn before it resumes.
Zero Sleep Yields
let probeprobe: Book.Concurrency.Timers.TimerProbe: TimerProbe @ global = TimerProbe { events = []; };
provide { Clock = Clock.virtualvirtual: pure fn!(start: Instant) -> Service.Provider(Clock)(epochepoch: Instant); } {
let startstart: Clock.MonotonicInstant = Clock.markmark: fn!() -> Clock.MonotonicInstant();
let otherother: Async.Task(Unit) = spawn {
recordrecord: fn(probe: Book.Concurrency.Timers.TimerProbe @ global, event: String @ global) -> Unit(probeprobe: Book.Concurrency.Timers.TimerProbe, "other""other": String);
};
Clock.sleepsleep: fn!(duration: Duration) -> Unit, eff Clock(Duration.zerozero: pure fn!() -> Duration());
recordrecord: fn(probe: Book.Concurrency.Timers.TimerProbe @ global, event: String @ global) -> Unit(probeprobe: Book.Concurrency.Timers.TimerProbe, "resumed""resumed": String);
await otherother: Async.Task(Unit);
expect ✓Clock.elapsed_sinceelapsed_since: fn!(mark: Clock.MonotonicInstant) -> Duration(startstart: Clock.MonotonicInstant) == Duration.zerozero: pure fn!() -> Duration();
};
expect ✓probeprobe: Book.Concurrency.Timers.TimerProbe.eventsevents: Vector(String) == ["other""other": String, "resumed""resumed": String];Interruption cancels the timer
Interrupting a sleeping fiber removes its deadline and runs its cleanup. The canceled deadline never advances virtual time.
Interrupt Cancels Sleep
let probeprobe: Book.Concurrency.Timers.TimerProbe: TimerProbe @ global = TimerProbe { events = []; };
provide { Clock = Clock.virtualvirtual: pure fn!(start: Instant) -> Service.Provider(Clock)(epochepoch: Instant); } {
let startstart: Clock.MonotonicInstant = Clock.markmark: fn!() -> Clock.MonotonicInstant();
let ownerowner: Async.Task(Int) = spawn {
let _sleeper_sleeper: Async.Task(Unit) = spawn {
defer recordrecord: fn(probe: Book.Concurrency.Timers.TimerProbe @ global, event: String @ global) -> Unit(probeprobe: Book.Concurrency.Timers.TimerProbe, "cleaned""cleaned": String);
Clock.sleepsleep: fn!(duration: Duration) -> Unit, eff Clock(Duration.hourshours: pure fn!(value: Int) -> Duration(11: Int));
recordrecord: fn(probe: Book.Concurrency.Timers.TimerProbe @ global, event: String @ global) -> Unit(probeprobe: Book.Concurrency.Timers.TimerProbe, "woke""woke": String);
};
Clock.sleepsleep: fn!(duration: Duration) -> Unit, eff Clock(Duration.secondsseconds: pure fn!(value: Int) -> Duration(11: Int));
77: Int
};
expect ✓await ownerowner: Async.Task(Int) == 77: Int;
expect ✓Clock.elapsed_sinceelapsed_since: fn!(mark: Clock.MonotonicInstant) -> Duration(startstart: Clock.MonotonicInstant) == Duration.secondsseconds: pure fn!(value: Int) -> Duration(11: Int);
};
expect ✓probeprobe: Book.Concurrency.Timers.TimerProbe.eventsevents: Vector(String) == ["cleaned""cleaned": String];Deadlines race work
A deadline is ordinary concurrent work. The first child to complete a Completion wins. Returning from the race fiber interrupts the losing child, so its timer never fires.
let first_replyfirst_reply: fn(reply_after: Duration @ global, deadline: Duration @ global) -> String = fn(reply_afterreply_after: Duration, deadlinedeadline: Duration) {
let racerace: Async.Task(String) = spawn {
let firstfirst: Completion(String) = Completion.makemake: pure fn!('a)() -> Completion(String)();
let _deadline_deadline: Async.Task(Unit) = spawn {
Clock.sleepsleep: fn!(duration: Duration) -> Unit, eff Clock(deadlinedeadline: Duration);
Completion.completecomplete: pure fn!('a)(completion: Completion(String), value: String @ global) -> Unit(firstfirst: Completion(String), "deadline""deadline": String);
};
let _reply_reply: Async.Task(Unit) = spawn {
Clock.sleepsleep: fn!(duration: Duration) -> Unit, eff Clock(reply_afterreply_after: Duration);
Completion.completecomplete: pure fn!('a)(completion: Completion(String), value: String @ global) -> Unit(firstfirst: Completion(String), "reply""reply": String);
};
await firstfirst: Completion(String)
};
await racerace: Async.Task(String)
};
Deadline Races Reply
provide { Clock = Clock.virtualvirtual: pure fn!(start: Instant) -> Service.Provider(Clock)(epochepoch: Instant); } {
let startstart: Clock.MonotonicInstant = Clock.markmark: fn!() -> Clock.MonotonicInstant();
expect ✓first_replyfirst_reply: fn(reply_after: Duration @ global, deadline: Duration @ global) -> String(Duration.secondsseconds: pure fn!(value: Int) -> Duration(22: Int), Duration.secondsseconds: pure fn!(value: Int) -> Duration(55: Int)) == "reply""reply": String;
expect ✓first_replyfirst_reply: fn(reply_after: Duration @ global, deadline: Duration @ global) -> String(Duration.secondsseconds: pure fn!(value: Int) -> Duration(99: Int), Duration.secondsseconds: pure fn!(value: Int) -> Duration(55: Int)) == "deadline""deadline": String;
expect ✓Clock.elapsed_sinceelapsed_since: fn!(mark: Clock.MonotonicInstant) -> Duration(startstart: Clock.MonotonicInstant) == Duration.secondsseconds: pure fn!(value: Int) -> Duration(77: Int);
};System time
Clock.SystemClock uses the host's monotonic clock. An idle scheduler waits for the earliest deadline instead of spinning, and still observes host cancellation while it waits.
System Clock Sleeps
provide { Clock = Clock.SystemClockSystemClock: service Clock; } {
let startstart: Clock.MonotonicInstant = Clock.markmark: fn!() -> Clock.MonotonicInstant();
Clock.sleepsleep: fn!(duration: Duration) -> Unit, eff Clock(Duration.zerozero: pure fn!() -> Duration());
expect ✓Duration.comparecompare: pure fn!(left: Duration, right: Duration) -> Int(
Clock.elapsed_sinceelapsed_since: fn!(mark: Clock.MonotonicInstant) -> Duration(startstart: Clock.MonotonicInstant),
Duration.zerozero: pure fn!() -> Duration(),
) >= 00: Int;
};