exisjs/cron
The exisjs/cron module provides background task scheduling, 5/6-field cron expression parsing, drift-corrected interval timers, retry backoff, and runtime job management.
Module Exports
import { cron, defineCron, CronManager, CronJob, CronExpression, every,} from 'exisjs/cron'
import type { CronSchedule, CronJobOptions, CronContext, CronJobStats, CronJobStatus, OverlapPolicy, IntervalOptions, TimeoutOptions,} from 'exisjs/cron'Decorators for class-based jobs are imported from exisjs/decorators:
import { Cron, Interval, TimeoutTask, Scheduled, ScheduledTimeout,} from 'exisjs/decorators'1. Functional Definition Helpers
cron(scheduleOrOptions, handler?)
Defines a functional cron job for auto-discovery or dynamic registration.
function cron( scheduleOrOptions: string | CronJobOptions, handler?: (ctx: CronContext) => any): FunctionalCronDefinitionOverloads
-
Option Object:
src/cron/sync.tsimport { cron, CronExpression } from 'exisjs/cron' export default cron({ name: 'sync-users', schedule: CronExpression.EVERY_10_MINUTES, timezone: 'UTC', preventOverlap: true, retries: 2, retryDelayMs: 1000, async run({ app, log, iteration }) { log.info({ iteration }, 'Running user synchronization') },}) -
Schedule Pattern & Handler:
src/cron/cleanup.tsimport { cron } from 'exisjs/cron' export default cron('0 0 * * *', async ({ log }) => { log.info('Running nightly purge')})
cron.every(duration, handler, options?)
Shorthand helper accepting natural language English duration strings (e.g., '10 seconds', '5 minutes', '2 hours', '1 day').
cron.every( duration: string, handler: (ctx: CronContext) => any, options?: Omit<CronJobOptions, 'schedule' | 'run' | 'handle'>): FunctionalCronDefinitionExample
import { cron } from 'exisjs/cron'
export default cron.every('15 minutes', async ({ log }) => { log.info('Heartbeat tick')}, { name: 'health-heartbeat', timezone: 'UTC',})cron.interval(ms, handler, options?)
Shorthand helper for millisecond recurring intervals with timer unref and drift management.
cron.interval( ms: number, handler: (ctx: CronContext) => any, options?: Omit<CronJobOptions, 'interval' | 'run' | 'handle'>): FunctionalCronDefinitionExample
import { cron } from 'exisjs/cron'
export default cron.interval(30_000, async ({ log }) => { log.info('Polling background job queue')})cron.timeout(ms, handler, options?)
Shorthand helper for one-time delayed startup tasks executed once after the server initializes.
cron.timeout( ms: number, handler: (ctx: CronContext) => any, options?: Omit<CronJobOptions, 'timeout' | 'run' | 'handle'>): FunctionalCronDefinitionExample
import { cron } from 'exisjs/cron'
export default cron.timeout(5_000, async ({ app, log }) => { log.info('Warming up memory cache after application startup')})2. OOP Decorators (exisjs/decorators)
@Cron(schedule, options?)
Method decorator that marks a class method on an @Injectable() service as a scheduled cron job.
function Cron( schedule: string, options?: Omit<CronJobOptions, 'schedule' | 'run' | 'handle'>): MethodDecorator| Parameter | Type | Description |
|---|---|---|
schedule | string | Standard 5 or 6 field cron expression or CronExpression constant. |
options | CronJobOptions | Optional job configuration (name, timezone, preventOverlap, retries, retryDelayMs). |
import { Injectable } from 'exisjs/di'import { Cron, CronExpression } from 'exisjs/decorators'
@Injectable()export class ReportService { @Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT, { name: 'nightly-report', timezone: 'UTC', preventOverlap: true, }) async generateDailyReport() { // Executes every day at 00:00 UTC }}@Interval(ms, options?)
Method decorator that schedules a method to run at recurring millisecond intervals.
function Interval( ms: number, options?: Omit<CronJobOptions, 'interval' | 'run' | 'handle'>): MethodDecoratorimport { Injectable } from 'exisjs/di'import { Interval } from 'exisjs/decorators'
@Injectable()export class MonitorService { @Interval(60_000, { name: 'health-monitor' }) async pingExternalServices() { // Runs every 60 seconds }}@TimeoutTask(ms, options?)
Method decorator for one-time startup tasks executed after the specified millisecond delay. Also aliased as @ScheduledTimeout.
function TimeoutTask( ms: number, options?: Omit<CronJobOptions, 'timeout' | 'run' | 'handle'>): MethodDecoratorimport { Injectable } from 'exisjs/di'import { TimeoutTask } from 'exisjs/decorators'
@Injectable()export class BootstrapService { @TimeoutTask(3_000, { name: 'seed-cache' }) async seedCache() { // Runs once 3s after server boot }}3. Configuration Interfaces
CronJobOptions
Configuration object accepted by cron(), app.cron.schedule(), and cron decorators:
| Option | Type | Default | Description |
|---|---|---|---|
name | string | job_<random> | Unique identifier for the job. Used in logging, statistics, and runtime triggers. |
schedule | string | undefined | 5 or 6 field cron expression (e.g. '0 0 * * *'). |
interval | number | undefined | Interval in milliseconds for recurring execution. |
timeout | number | undefined | Delay in milliseconds for one-time execution. |
timezone | string | 'UTC' | IANA timezone string (e.g. 'America/New_York', 'Asia/Kolkata'). |
preventOverlap | boolean | true | When true, skips execution if the previous execution is still running. |
onOverlap | 'skip' | 'queue' | 'skip' | Overlap policy when a job is triggered while already running. |
autoStart | boolean | true | Whether the job begins scheduling automatically upon registration. |
retries | number | 0 | Number of retry attempts if the handler throws an unhandled error. |
retryDelayMs | number | 1000 | Delay between retry attempts in milliseconds. |
run / handle | (ctx: CronContext) => any | undefined | Main execution callback function. |
onError | (err: Error, ctx: CronContext) => void | undefined | Error hook executed if the handler fails all retry attempts. |
CronContext
Context object passed to cron execution handlers:
| Property | Type | Description |
|---|---|---|
app | App | The active ExisJS application instance. |
log | Logger | Structured application logger instance. |
jobName | string | The unique name of the currently executing job. |
startedAt | Date | Timestamp when the current execution began. |
iteration | number | Monotonically increasing execution counter for this job instance. |
signal | AbortSignal | AbortSignal triggered during application graceful shutdown. |
CronJobStats
Statistics descriptor returned by job.getStats() and app.cron.getStats():
| Field | Type | Description |
|---|---|---|
name | string | Unique job identifier. |
status | 'idle' | 'running' | 'paused' | 'stopped' | Current job execution status. |
schedule | string | undefined | Configured cron schedule expression. |
intervalMs | number | undefined | Configured interval in milliseconds. |
timezone | string | undefined | Configured IANA timezone. |
preventOverlap | boolean | Overlap prevention status. |
lastRun | Date | undefined | Timestamp of the most recent execution. |
nextRun | Date | undefined | Calculated timestamp for the upcoming scheduled run. |
executionCount | number | Total number of executions attempted. |
failureCount | number | Total number of failed executions. |
lastDurationMs | number | undefined | Duration in milliseconds of the last execution. |
lastError | string | undefined | Last error message if execution failed. |
4. CronExpression Constants
ExisJS exports pre-compiled cron patterns:
| Constant | Value | Description |
|---|---|---|
CronExpression.EVERY_SECOND | * * * * * * | Every second (6-field) |
CronExpression.EVERY_5_SECONDS | */5 * * * * * | Every 5 seconds (6-field) |
CronExpression.EVERY_10_SECONDS | */10 * * * * * | Every 10 seconds (6-field) |
CronExpression.EVERY_30_SECONDS | */30 * * * * * | Every 30 seconds (6-field) |
CronExpression.EVERY_MINUTE | * * * * * | Every minute |
CronExpression.EVERY_2_MINUTES | */2 * * * * | Every 2 minutes |
CronExpression.EVERY_3_MINUTES | */3 * * * * | Every 3 minutes |
CronExpression.EVERY_5_MINUTES | */5 * * * * | Every 5 minutes |
CronExpression.EVERY_10_MINUTES | */10 * * * * | Every 10 minutes |
CronExpression.EVERY_15_MINUTES | */15 * * * * | Every 15 minutes |
CronExpression.EVERY_30_MINUTES | */30 * * * * | Every 30 minutes |
CronExpression.EVERY_HOUR | 0 * * * * | At minute 0 of every hour |
CronExpression.EVERY_2_HOURS | 0 */2 * * * | Every 2 hours |
CronExpression.EVERY_3_HOURS | 0 */3 * * * | Every 3 hours |
CronExpression.EVERY_6_HOURS | 0 */6 * * * | Every 6 hours |
CronExpression.EVERY_12_HOURS | 0 */12 * * * | Every 12 hours |
CronExpression.EVERY_DAY_AT_MIDNIGHT | 0 0 * * * | Daily at 00:00 (Midnight) |
CronExpression.EVERY_DAY_AT_1AM | 0 1 * * * | Daily at 01:00 AM |
CronExpression.EVERY_DAY_AT_2AM | 0 2 * * * | Daily at 02:00 AM |
CronExpression.EVERY_DAY_AT_NOON | 0 12 * * * | Daily at 12:00 PM |
CronExpression.EVERY_WEEK | 0 0 * * 0 | Every Sunday at 00:00 |
CronExpression.EVERY_WEEKDAY | 0 0 * * 1-5 | Monday through Friday at 00:00 |
CronExpression.EVERY_WEEKEND | 0 0 * * 6,0 | Saturday and Sunday at 00:00 |
CronExpression.EVERY_MONTH | 0 0 1 * * | First day of every month at 00:00 |
CronExpression.EVERY_QUARTER | 0 0 1 1,4,7,10 * | First day of every quarter at 00:00 |
CronExpression.EVERY_YEAR | 0 0 1 1 * | January 1st at 00:00 |
5. every(duration) Helper
Converts human-readable duration strings into standard 5 or 6 field cron patterns.
function every(duration: string): string| Input Example | Generated Cron Pattern |
|---|---|
every('10 seconds') | */10 * * * * * |
every('5 minutes') | */5 * * * * |
every('2 hours') | 0 */2 * * * |
every('1 day') | 0 0 * * * |
every('1 week') | 0 0 * * 0 |
every('1 month') | 0 0 1 * * |
6. Runtime Management (CronManager)
Access the application cron manager instance via app.cron:
export class CronManager { has(name: string): boolean schedule(nameOrOptions: string | CronJobOptions, schedule?: string, handler?: (ctx: CronContext) => any, options?: Partial<CronJobOptions>): CronJob interval(name: string, ms: number, handler: (ctx: CronContext) => any, options?: Partial<CronJobOptions>): CronJob timeout(name: string, ms: number, handler: (ctx: CronContext) => any, options?: Partial<CronJobOptions>): CronJob getJob(name: string): CronJob | undefined getJobs(): Map<string, CronJob> getStats(): CronJobStats[] startAll(): void pauseAll(): void stopAll(): void trigger(name: string): Promise<any> drain(timeoutMs?: number): Promise<void>}Examples
// Check if a job existsif (app.cron.has('sync-users')) { // Retrieve execution metrics const job = app.cron.getJob('sync-users') console.log(job?.getStats())}
// Manually trigger immediate executionawait app.cron.trigger('sync-users')
// Pause all jobs during maintenanceapp.cron.pauseAll()
// Resume schedulingapp.cron.startAll()
// Gracefully drain in-flight jobs during shutdownawait app.cron.drain(5000)