Scheduler
import { Scheduler } from 'anarchon';Constructor
Section titled “Constructor”new Scheduler(options: SchedulerOptions)Creates a scheduler. Nothing connects until start(). backend is required: no store is assumed. See Options.
Throws TypeError when backend is not given, or instanceId is empty; RangeError when a number is out of range, or heartbeatMs is not under half of leaseMs.
Properties
Section titled “Properties”| Property | Type | Meaning |
|---|---|---|
instanceId |
string |
This instance’s name in history and events |
backend |
Backend |
The backend in use. backend.name is e.g. 'redis:lease' or 'postgres' |
name |
string | undefined |
The name decorated jobs choose this scheduler by, if it has one |
Defining jobs
Section titled “Defining jobs”All three return the scheduler, so they chain.
every(name, interval, handler, options?)
Section titled “every(name, interval, handler, options?)”every(name: string, interval: number | string, handler: JobHandler, options?: EveryJobOptions): thisAdds an interval job. interval is ms or a duration string ('10s', '35m', '1h30m', '2d'). Minimum 1 second. Runs fall on a UTC grid.
Throws RangeError for an invalid or too short interval, or unsafe timings; Error if the name is already registered.
cron(name, expression, handler, options?)
Section titled “cron(name, expression, handler, options?)”cron(name: string, expression: string, handler: JobHandler, options?: CronJobOptions): thisAdds a cron job. Five fields, or six with seconds first.
Throws Error for an invalid expression or a duplicate name; RangeError if the expression never runs in the future, or for unsafe timings.
at(name, when, handler, options?)
Section titled “at(name, when, handler, options?)”at(name: string, when: Date | number | string, handler: JobHandler, options?: JobOptions): thisAdds a one-off job. when is a Date, ms since 1970, or an ISO string.
Throws RangeError for an invalid date.
register(target, options?)
Section titled “register(target, options?)”register(target: object, options?: { prefix?: string; defaults?: JobOptions & { timezone?: string } }): thisPuts every job declared with @Cron, @Every and @At on the object’s class on this scheduler, whatever scheduler each decorator names. Each job calls its method on that object, and is named Class-method unless the decorator gives a name. Adds all the jobs or none.
A decorated object adds its jobs by itself when it is created, so you call this to decide something for one object: prefix goes in front of every job name, so several objects of one class can coexist, and defaults are job options for every job of the object. It is also how an object is added with legacy decorators on a class without @Scheduled(). Registering an object again with options replaces its jobs; without options it changes nothing.
Throws TypeError if the class has no decorated methods; otherwise what every(), cron() and at() throw.
Guide: Decorators. Reference: Decorators.
remove(name)
Section titled “remove(name)”remove(name: string): booleanStops scheduling a job on this instance. Returns false if no job has that name. History is kept; a run in progress here finishes.
Guide: Defining jobs.
Lifecycle
Section titled “Lifecycle”start()
Section titled “start()”start(): Promise<void>Connects, prepares the jobs, schedules them, and on a lease backend recovers unfinished and missed runs. Does nothing if already running.
Rejects when the backend can’t be reached or is too old. The scheduler stays stopped.
Throws Error if called while starting or stopping.
stop(options?)
Section titled “stop(options?)”stop(options?: { timeoutMs?: number }): Promise<void>Stops scheduling, aborts ctx.signal of running jobs, waits up to timeoutMs (default 30000) for them, and closes connections the backend opened. Calling it again while stopping returns the same promise.
runNow(name, options?)
Section titled “runNow(name, options?)”runNow(name: string, options?: { data?: JobData }): Promise<RunRecord>Runs a job now on this instance. Not deduplicated, never retried, recorded with manual: true. Resolves with the run’s record when the handler has finished. data is data for this one run, on top of the job’s and the scheduler’s: see Run data.
Throws Error if the job isn’t registered here or the scheduler isn’t started.
Guide: Lifecycle.
setData(data)
Section titled “setData(data)”setData(data: JobData | undefined): thisReplaces the scheduler’s data, the data handed to every handler as ctx.data under each job’s own. Runs that start afterwards get the new one; runs in progress keep theirs. undefined removes it.
Guide: Run data.
Schedulers for decorated jobs
Section titled “Schedulers for decorated jobs”Static methods that create, find, start and stop the schedulers decorated jobs go to. They are described in the Decorators reference.
| Method | What it does |
|---|---|
Scheduler.configure(options), Scheduler.configure(name, options) |
Stores the settings a scheduler is created from when a job needs it. A backend must be given |
Scheduler.get(name?) |
The default scheduler or a named one, created from its settings if it doesn’t exist |
Scheduler.all() |
The default scheduler and every named one |
Scheduler.startAll(), Scheduler.stopAll(options?) |
Start or stop all of them |
Scheduler.setDefault(scheduler) |
Chooses the default scheduler |
Scheduler.reset() |
Forgets schedulers, names and settings. For tests |
Reading
Section titled “Reading”history(name, limit?)
Section titled “history(name, limit?)”history(name: string, limit?: number): Promise<RunRecord[]>The latest runs from all instances, newest first, one record per attempt. limit is 1 to 10000, default 20. Works for any job name and before start().
Throws RangeError for a limit out of range.
lastRun(name)
Section titled “lastRun(name)”lastRun(name: string): Promise<RunRecord | null>The most recent attempt, or null if the job never ran.
nextRun(name)
Section titled “nextRun(name)”nextRun(name: string): Date | nullWhen a registered job is next due, or null if it has no more runs.
Throws Error if the job isn’t registered here.
jobs()
Section titled “jobs()”jobs(): JobInfo[]The jobs registered on this instance: name, type, schedule, nextRunAt, runningHere.
Guide: History.
Events
Section titled “Events”on<E extends keyof SchedulerEvents>(event: E, listener: (payload: SchedulerEvents[E]) => void): thisonce<E extends keyof SchedulerEvents>(event: E, listener: (payload: SchedulerEvents[E]) => void): thisoff<E extends keyof SchedulerEvents>(event: E, listener: (payload: SchedulerEvents[E]) => void): thisSee Events.
Exports
Section titled “Exports”Everything the package exports.
| Export | Kind | Purpose |
|---|---|---|
Scheduler |
class | The scheduler |
RedisBackend |
class | Redis and Valkey |
ValkeyBackend |
class | Redis and Valkey |
PostgresBackend |
class | PostgreSQL |
SqliteBackend |
class | SQLite and libSQL |
RabbitMQBackend |
class | RabbitMQ |
NatsBackend |
class | NATS |
SqlBackend |
abstract class | Base of the two SQL backends |
LeaseStore |
class | The Redis lease implementation |
Cron, Every, At |
decorators | Declare jobs on the methods of a class |
Scheduled |
decorator | For classes compiled with legacy decorators |
parseDuration, formatDuration |
functions | '1h30m' to ms, and back |
buildHistory |
function | Joins a job’s claims and results into history records, for a custom backend |
fromIORedis, fromNodeRedis, fromValkeyGlide |
functions | Adapt a Redis client to { send } |
fromPgPool, fromPgClient, fromPostgresJs |
functions | Adapt a Postgres client to { all, transaction } |
fromSqliteDatabase, fromLibsql |
functions | Adapt a SQLite database or libSQL client |
| Types | types | See Types |
You rarely need the from... adapters: every backend recognizes these clients on its own. They are exported for building your own client wrappers.
parseDuration and formatDuration
Section titled “parseDuration and formatDuration”import { formatDuration, parseDuration } from 'anarchon';
parseDuration('1h30m'); // 5400000parseDuration('500ms'); // 500parseDuration(10_000); // 10000formatDuration(5_400_000); // '1h30m'