Skip to main content

Recurring jobs

A recurring job runs on a cron schedule with no payload. Register it with the @worker.recurring(...) decorator:

from zeridion_flare.worker import FlareWorker, JobContext

worker = FlareWorker()

@worker.recurring("NightlyCleanup", cron="0 3 * * *", queue="maintenance", timezone="UTC")
def nightly(ctx: JobContext) -> None:
purge_expired()

A recurring handler takes a single positional parameter, the JobContext. There is no payload.

The worker does not self-enqueue

When the worker starts, it registers its recurring schedules with Zeridion. The server fires each schedule on its cron and delivers the resulting job back to the worker through the normal poll loop. The worker never enqueues its own recurring work — so running several worker replicas does not multiply the schedule.

Time zones matter

timezone takes an IANA name (for example "UTC", "America/New_York", "Europe/Berlin"). The cron expression is evaluated in that zone. Always set it for a non-UTC schedule — otherwise 0 3 * * * runs at 3 AM in the server's default zone, not yours.

@worker.recurring(
"DailyReport",
cron="30 8 * * 1-5", # 08:30 on weekdays
queue="reports",
timezone="America/New_York", # …New York time
)
def daily_report(ctx: JobContext) -> None:
build_report()

Configuration

ArgumentDefaultMeaning
cronrequiredStandard 5-field cron expression.
queue"default"The queue the recurring job is served from.
timezoneserver defaultIANA time zone the cron is evaluated in.
max_attempts3Advertised attempt ceiling.
timeout1800 (30 min)Per-run timeout in seconds.

Cancellation

Like any job, a recurring run can be cancelled (on shutdown or timeout). Honor ctx.is_cancelled() so a long sweep stops promptly — see Job context.

See also