gizweb:jobs
An app's durable jobs: a queue of one-off jobs and named recurring ones in one record. A job names a path of the app that runs it. Delivery can repeat, so a handler uses the job's id to stay idempotent. A job has MAX_ATTEMPTS attempts, retried after 1 s, then 2 s; a claim holds a LEASE_MS lease, so the job of a worker that died is claimed again. Every change is a compare-and-set on the record, so two workers never settle one claim.
import * as Jobs from "gizweb:jobs";Types
Job
type Job = { @Key id: string; path: string; payload: string; due: i64; @Column("interval_ms") intervalMs: i64; attempts: i64; state: string; lease: i64; error: string; }One job. due is when it may run (ms); lease is when the running claim ends; a recurring job has intervalMs.
id:stringpath:stringpayload:stringdue:i64intervalMs:i64attempts:i64state:string— pending, running, done or failed.lease:i64error:string
Functions
install
function install(d: Data.Db): bool throws Model.RejectionMakes the jobs table when it is not there.
Effects: fail, read, write, console, io.
enqueue
function enqueue(d: Data.Db, id: string, path: string, payload: string, due: i64): bool throws Model.RejectionQueues a job of PATH with PAYLOAD under the fresh ID, due at DUE.
Effects: fail, read, write, console, io.
schedule
function schedule(d: Data.Db, name: string, path: string, interval: i64, due: i64): bool throws Model.RejectionRuns PATH every INTERVAL ms under the job id "schedule:NAME", first at DUE. A second call changes its path and interval and keeps its state.
Effects: fail, read, write, console, io.
next
function next(d: Data.Db): Option<i64> throws Model.RejectionWhen the next job is due or its lease ends, so a worker sleeps until then; none when no job waits. A running job whose attempts are spent counts too: its claimant finalizes it.
Effects: fail, read, write, console, io.
claim
function claim(d: Data.Db, now: i64): Option<Job> throws Model.RejectionClaims the job that is due first at NOW, if any, with a fresh lease. A running job whose lease ended and whose attempts are spent ends here: failed, or, when it recurs, due again one interval later.
Effects: fail, read, write, console, io.
finish
function finish(d: Data.Db, job: Job, error: string, now: i64): bool throws Model.RejectionSettles the claim JOB at NOW: done, or, with an ERROR, due again until its attempts are spent. A recurring job is due again one interval after its last due time. False when JOB is no longer the current claim.
Effects: fail, read, write, console, io.
Constants
MAX_ATTEMPTS
const MAX_ATTEMPTS = 3The runs a job gets before it fails for good.
LEASE_MS
const LEASE_MS = 30000How long a claim holds a job before another worker may take it again.