Skip to main content

Scheduler options

stack.jobScheduler is created with the stack and started by the application. See Background jobs and scheduling for the reasoning; this page is the surface.

start(options)

OptionDefaultMeaning
jobsrequiredJob ids allowed to run unattended. There is deliberately no "all".
pinnedHashes{}Expected hash per job. A mismatch skips the job with hash-mismatch.
intervalMs60000Floor between automatic ticks. Values below 5000 are raised to it.
staleRunMs900000 (15 minutes)A ~JobRun left RUNNING longer than this is swept to CANCELED. At most 50 per tick.
backoffBaseMs300000 (5 minutes)First retry delay after a failure; doubles per consecutive failure.
maxBackoffMs21600000 (6 hours)Ceiling for that doubling.
nowDate.nowInjectable clock, for tests.
onRunnoneCalled with each completed ~JobRun, successful or not.

start evaluates once immediately, then on every interval.

Methods

MethodReturnsNotes
start(options)voidBegin scheduling.
tick()Promise<TickReport>Evaluate now. Idempotent: concurrent calls share one evaluation. Call it from wake signals such as visibilitychange.
stop()voidStop scheduling. Jobs already dispatched keep running; a hydrated function has no cancel.
drain()Promise<void>Resolves when every job this scheduler started has finished.
status(){ running, inFlight, jobs }What the scheduler believes, without a database round-trip. jobs maps job id to its JobScheduleState.
isRunningbooleanGetter.

Schedule grammar

Set on the job document's schedule field.

FormMeaning
@every <n><unit>A fixed interval since the last run. Units s, m, h, d, w. Not shorter than 30 seconds.
@hourlyThe top of each local hour.
@dailyLocal midnight.
@daily@HH:MMA local wall-clock time, 24-hour.
@weeklyMonday, local midnight.
@weekly@HH:MMMonday at a local wall-clock time.

Anchored forms are computed in local time, so they follow the device across daylight-saving changes. Cron expressions are not accepted: parseSchedule returns null and the job is skipped with unparseable-schedule. Missed occurrences collapse into one run.

parseSchedule(text) and nextOccurrence(schedule, from) are exported by @docstack/client for applications that want to show "next run" in a UI.

TickReport

FieldMeaning
atThe instant the tick was evaluated at.
dispatchedJob ids dispatched by this tick. They may still be running when the report returns.
skipped{ jobId, reason } per job not dispatched.
sweptRunsAbandoned RUNNING runs moved to CANCELED.

Skip reasons: missing (no such job document), disabled, no-schedule, unparseable-schedule, hash-mismatch, in-flight, not-due.

Schedule state

Kept in the _local/docstack-job-schedule document (JOB_SCHEDULE_DOC_ID), which never replicates. Per job:

FieldMeaning
nextRunAtWhen this job next comes due on this device.
lastRunAtWhen this device last dispatched it.
lastStatusThe outcome of that dispatch.
consecutiveFailuresDrives the backoff. Reset by any success.
scheduleThe schedule string the state was computed from; a change resets the state.