Module time/sleep
Sleeping — one async form and one blocking form, both taking a Duration.
sleep suspends the calling async task and lets the event loop run other
work; sleep_blocking parks the whole OS thread. Prefer sleep inside
async code — sleep_blocking there would stall every other task on the
loop.
The underlying timers take whole milliseconds, so sub-millisecond
precision in the Duration is truncated — a Duration.from_micros(500)
sleeps for no time at all. A NEGATIVE Duration is worse than that: both
forms cast the millisecond count to an unsigned type, so it becomes a wait
of ~585 million years rather than an immediate return
(issues/stddoc-io-negative-duration-sleeps-forever.md). Pass a span you
know to be non-negative until that is fixed.
interval is the third form: a repeating tick that does NOT drift, which a
sleep in a loop does. See its own doc.
Example
{ sleep, sleep_blocking } :: import "std/time/sleep";
{ Duration } :: import "std/time/duration";
// Blocking: parks this thread for 100ms.
sleep_blocking(Duration.from_millis(i64(100)));
// Async: suspends this task for 100ms.
main :: (fn(io : Io) -> unit)({
io.await(sleep(Duration.from_millis(i64(100)), io), io);
});
Stability
unstable — interval landed 2026-09-10 (#532) and has had one release,
and it ships exactly one missed-tick policy. tick() BURSTS to catch up,
which is Tokio's MissedTickBehavior::Burst default and right for
anything that counts ticks, but wrong for a rate limiter; Tokio's Delay
and Skip are deliberately not implemented until a call site needs one,
so the selector that would carry them (a constructor argument, or
set_missed_tick_behavior) is an unmade decision in this module's surface.
The other open item is the input contract the two sleep forms share:
the millisecond floor and the negative-Duration hole above are properties
of the code, not of any signature, and freezing them would freeze the hole.
sleep / sleep_blocking themselves — the names, the split, and the rule
that async code uses sleep — are settled.
Types
A repeating tick — Tokio's interval.
Why this exists rather than sleep in a loop. while(true, { work(); sleep(period); }) DRIFTS: each iteration takes period + work, so after
100 ticks of 10 ms work on a 1 s period the clock is 1 s behind. An
interval anchors every tick to a SCHEDULE — tick n is due at
start + n * period — so the work duration comes out of the wait instead
of being added to it.
t := interval(Duration.from_millis(i64(100)), io);
io.await(t.tick(io), io); // completes immediately
io.await(t.tick(io), io); // completes 100ms after the FIRST tick
The first tick() completes immediately, as Tokio's does: an interval is
almost always driving a loop whose first pass should not be delayed.
Fields
| Name | Type | Description |
|---|---|---|
_period | Duration | |
_next | Instant | When the next tick is DUE. Advanced by exactly one period per tick, so the schedule is never re-anchored to "now". |
impl(Interval, ...)
tick : (Interval) fn(self : Interval, io : Io) -> Impl : (Future[Future](unit))Wait until the next tick is due.
Missed ticks BURST. If the caller's work overran the period, _next
is already in the past and this returns immediately, then advances by one
period — so the ticks the stall swallowed are delivered back to back
until the schedule is caught up. That is Tokio's default
(MissedTickBehavior::Burst) and it is right for anything that counts
ticks (sampling, accounting): the total number of ticks over an interval
is what the period promises.
It is WRONG for a rate limiter, which wants the stall to swallow the
ticks rather than repay them. That is Tokio's Delay/Skip, and it is
deliberately not implemented until something needs it — the choice has
to be made per call site and guessing it here would be worse than
leaving it out.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Interval | |
io | Io |
Returns: Impl : (Future[Future](unit))
Functions
Block the current thread for duration. Nothing else runs on this thread
until it returns — inside async code use sleep instead.
Parameters
| Name | Type | Notes |
|---|---|---|
duration | Duration |
Returns: unit