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
| Argument | Default | Meaning |
|---|---|---|
cron | required | Standard 5-field cron expression. |
queue | "default" | The queue the recurring job is served from. |
timezone | server default | IANA time zone the cron is evaluated in. |
max_attempts | 3 | Advertised attempt ceiling. |
timeout | 1800 (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.