Declare cron schedules on :wagoe/jobs. Each tick enqueues a job of that
type; the handler is the one registered for it.
:wagoe/jobs {:provider :db
:recurring {:nightly-report {:cron "0 2 * * *"
:zone "Europe/Amsterdam"
:args {:kind :sales}}}
:scheduler {:tick-ms 5000 :lease-ms 30000 :zone "UTC"}}
Or at runtime, on the :wagoe/job-scheduler component:
(require '[wagoe.jobs.shell.recurring :as recurring])
(recurring/schedule-recurring! scheduler :nightly-report "0 2 * * *"
{:zone "Europe/Amsterdam" :queue :reports})
Expressions have five fields (minute, hour, day of month, month, day of
week) with *, lists, ranges, steps and names (MON, JAN), plus
@hourly, @daily, @weekly, @monthly and @yearly. A malformed
expression, an unknown zone, or one that never fires fails the boot. A job
type with no handler on the node is logged as a warning by the lease holder,
on its first tick, with the types that have one: it does not fail the boot, because a handler may be
registered after boot or run only on worker nodes.
-
One replica enqueues. Every replica runs a ticker; the one holding a
lease enqueues (a database row timed by the database clock under :db,
SET NX PX under :redis). Each tick is also claimed as an idempotency key,
job type plus scheduled instant, so two tickers overlapping after a lease
handover still enqueue it once.
-
Zones are wall-clock. The zone defaults to UTC. A time skipped by a DST
jump runs at the shifted instant; a time that occurs twice runs once.
-
Missed ticks run at most once. After downtime a schedule runs its latest
missed tick once and skips the earlier ones. A new schedule does not run for
ticks before it was registered.
-
A tick is enqueued at most once. A process that dies between claiming a
tick and enqueueing it loses that tick.
-
:provider :memory keeps all of this in one process.