x.scheduler #
In-process scheduler
Scheduler runs interval and daily jobs sequentially in one loop thread. Register jobs before calling start, and call stop to wait for the loop to finish.
The loop ticks once per second. Positive intervals passed to every are rounded up to whole seconds, so a 1500 millisecond interval runs at most once every two seconds. Interval jobs also run on the first tick after startup. run_pending accepts a Unix timestamp in seconds for deterministic scheduling without starting the loop.
Daily jobs run when a tick falls inside the requested minute; missed times are not replayed.
struct Job #
struct Job {
name string
f fn () @[required]
mut:
every_secs i64
daily_hour int = -1
daily_min int
last_run i64
}
Job is one named unit of scheduled work. Create it through Scheduler.every or Scheduler.daily_at and never touch it again: the scheduler owns it from start on. Jobs run sequentially in the loop thread, to completion, in registration order — so a job can neither overlap itself nor race another. A job that needs concurrency spawns it internally.
struct Scheduler #
struct Scheduler {
mut:
jobs []&Job
stopped &stdatomic.AtomicVal[bool] = stdatomic.new_atomic(false)
started bool
thread thread
}
Scheduler runs named jobs in one process on intervals or daily times. The loop ticks once a second and runs what is due, sequentially, to completion. The struct is heap-allocated so start can hand it to its loop thread.
fn (Scheduler) every #
fn (mut s Scheduler) every(name string, interval time.Duration, f fn ()) &Job
every schedules f to run every interval under name. The job also runs on the first tick after start, since it has never run. Positive intervals are rounded up to whole seconds to match the loop's tick resolution.
fn (Scheduler) daily_at #
fn (mut s Scheduler) daily_at(name string, hour int, minute int, f fn ()) &Job
daily_at schedules f to run once a day at hour:minute under name. The job fires when a tick lands inside its minute; a scheduler started after today's time simply waits for tomorrow.
fn (Scheduler) run_pending #
fn (mut s Scheduler) run_pending(now_unix i64) int
run_pending runs every job that is due at now_unix (Unix seconds), sequentially and to completion, and returns how many ran. It is the loop body factored out so tests can drive time directly. Keep jobs short: a long job delays the ticks behind it.
fn (Scheduler) start #
fn (mut s Scheduler) start()
start launches the scheduling loop in its own thread. Call it once; a second call does nothing.
fn (Scheduler) stop #
fn (mut s Scheduler) stop()
stop asks the loop to exit after its current tick and waits for it. A job that is running finishes first, because jobs run inside the loop thread.