Temporal decorators

Scheduling decorators register a named function with the runtime so it fires without a direct caller. Every form takes a Duration literal (or a plain number, treated as milliseconds).

Summary

Four decorators cover scheduling: @every(dur) for an interval, @delayed(dur) for a one-shot delay, @cron("expr") for cron expressions, and @watch("path") for filesystem changes. They attach to a named function declaration, not to a bare block. The earlier statement-form syntax (every 1s { ... }) is no longer accepted; the parser only knows the decorator form.

@every

Repeats the body at a fixed interval.

@every(1s)
fn tick() {
    metrics.flush()
}

@delayed

Runs the body once after the given delay, then unregisters.

@delayed(500ms)
fn warmup() {
    prefetch()
}

@cron

Takes a five-field cron expression (min hour day month weekday) and fires whenever the local clock matches.

@cron("0 9 * * 1-5")
fn weekday_morning() {
    digest.send()
}

@watch

Fires whenever the watched path changes on disk. Useful for hot-reload loops in development.

@watch("./config.toml")
fn reload() {
    config.reload()
}

Runtime lifetime

The runtime stays alive while any persistent trigger is registered. Once every @delayed has fired and every @every/ @cron / @watch has been quiesced (typically with @once), the process exits naturally. xs.exit(n) forces a shutdown and still fires @on_exit handlers.

See also decorators for the full list (lifecycle, signal, discovery, wrapping).