Java worker
The com.zeridion:flare package ships a built-in background-worker runtime in
the opt-in com.zeridion.flare.worker package. Thin-client users who only
enqueue jobs pay nothing for it; importing the worker package turns the same
artifact into a full worker host.
A worker:
- registers itself with Flare (its id, served queues, job types, and any recurring schedules),
- long-polls for jobs on its queues,
- dispatches each job to your handler with bounded concurrency,
- heartbeats while a job runs (carrying progress, and reacting if Flare asks to cancel),
- acks the outcome (succeeded or failed), and
- drains gracefully on SIGTERM/SIGINT — finishing in-flight jobs before it exits.
It reuses the FlareClient transport (authentication, timeouts, the response
cap) and adds no new mandatory dependency.
Requirements
- Java 17+ (LTS).
- A
FlareClient(the worker reuses its transport).
<dependency>
<groupId>com.zeridion</groupId>
<artifactId>flare</artifactId>
<version>0.2.1</version>
</dependency>
Quick start
Define a job, register it on a worker, and run:
import com.zeridion.flare.FlareClient;
import com.zeridion.flare.worker.*;
@FlareJob(name = "SendWelcomeEmail", queue = "default", maxAttempts = 5, timeoutSeconds = 60)
public final class SendWelcomeEmail implements Job<NewUserEvent> {
public void execute(NewUserEvent payload, JobContext ctx) {
if (ctx.isCancellationRequested()) return;
mailer.send(payload.email); // make this idempotent (see below)
ctx.reportProgress(1.0);
}
}
FlareClient client = FlareClient.builder().build(); // FLARE_API_KEY from env
FlareWorker worker = FlareWorker.builder(client)
.options(WorkerOptions.builder().concurrency(5).build())
.register(SendWelcomeEmail.class, NewUserEvent.class, SendWelcomeEmail::new)
.build();
worker.run(); // blocks until SIGTERM/SIGINT, then drains
run() installs a shutdown hook and blocks. For embedded control, use
start() (returns immediately) and stop() (idempotent; drains). The worker is
also AutoCloseable, so it works in a try-with-resources block.
The one rule: idempotent handlers
Acks are best-effort, so delivery is at-least-once: if a process dies after
the work completes but before the ack reaches Flare, the job is delivered again.
Write every handler so that running it twice for the same job is safe — guard
side effects on ctx.jobId():
public void execute(NewUserEvent payload, JobContext ctx) {
if (alreadyProcessed(ctx.jobId())) return; // dedupe on the job id
mailer.send(payload.email);
markProcessed(ctx.jobId());
}
Worker identity
Each worker generates a stable id of the form wrk_<host>_<pid>_<random>. The
host is sanitised to the characters Flare accepts and the random suffix comes
from a secure generator, so two workers on the same machine (or sharing a
container hostname) never collide.
Next
- Handlers — defining payload jobs, payload binding, errors.
- Recurring jobs — cron schedules with a timezone.
- Job context — ids, attempt counters, progress, logging.
- Configuration — concurrency, queues, timeouts, drain.
- Cancellation — cooperative cancellation and timeouts.