Recurring jobs
A recurring job runs on a cron schedule and takes no payload. Implement
RecurringJob and put the schedule on @FlareJob:
import com.zeridion.flare.worker.FlareJob;
import com.zeridion.flare.worker.JobContext;
import com.zeridion.flare.worker.RecurringJob;
@FlareJob(name = "NightlyCleanup", cron = "0 3 * * *", queue = "maintenance", timezone = "UTC")
public final class NightlyCleanup implements RecurringJob {
public void execute(JobContext ctx) throws Exception {
db.purgeExpiredSessions();
}
}
Register it with registerRecurring:
FlareWorker.builder(client)
.registerRecurring(NightlyCleanup.class, NightlyCleanup::new)
.build();
How the schedule is applied
When the worker starts, it announces every recurring schedule to Flare as part of registration. Flare owns the timer: it evaluates the cron expression and, on each due tick, enqueues a run that the worker picks up through the same poll loop as any other job. Your worker does not run its own scheduler.
Always set the timezone
cron alone is ambiguous — 0 3 * * * means "03:00", but 03:00 where? Set
timezone to an IANA zone (for example "UTC", "America/New_York",
"Europe/Berlin") so the schedule fires at the wall-clock time you intend. If
you omit it, Flare applies a default zone, which is almost certainly not what a
non-UTC schedule wants.
Idempotency still applies
Like payload jobs, a recurring run is delivered at-least-once, so the handler
must be safe to run more than once for the same scheduled occurrence. Guard any
non-idempotent side effect on ctx.jobId().
Configuration carried with the schedule
queue, maxAttempts, and timeoutSeconds from the annotation are announced
alongside the schedule, so a recurring run is retried and timed out using the
same rules as a directly-enqueued job.