Skip to main content

PHP worker

The zeridion/flare package ships a built-in worker under the Zeridion\Flare\Worker namespace. Define your jobs as classes, register them, and the worker announces itself, long-polls for work, dispatches each job to its handler, heartbeats with progress, honours server-side cancellation, and drains the in-flight job on shutdown.

The worker is opt-in — importing it does not change the thin client, so a project that only enqueues jobs stays lean.

Install

composer require zeridion/flare

For background heartbeats and graceful SIGTERM shutdown, also enable the optional ext-pcntl and ext-posix extensions. Without them the worker still runs, with coarser liveness and no preemptive cancellation (see Cancellation & timeouts).

One job per process

Stock PHP has no shared-memory threads, so the worker runs one job per process. Scale throughput by running multiple worker processes under a process supervisor — see Running a fleet. A concurrency greater than 1 is accepted but has no effect on a single process and logs a warning at startup.

Quick start

<?php
require __DIR__ . '/vendor/autoload.php';

use Zeridion\Flare\Worker\FlareWorker;
use Zeridion\Flare\Worker\WorkerOptions;

$worker = new FlareWorker(WorkerOptions::fromEnv());
$worker->register(SendWelcomeEmail::class);
$worker->register(NightlyCleanup::class);

exit($worker->run());

run() blocks until the process receives SIGTERM / SIGINT, then finishes the in-flight job and returns an exit code (0 = clean shutdown).

Define SendWelcomeEmail and NightlyCleanup with the #[FlareJob] attribute — see Defining a payload job and Recurring jobs.

What the worker does

On run() the worker:

  1. Builds a stable worker id of the form wrk_{host}_{pid}_{random} (the host is sanitised and a cryptographically-random suffix is appended so two workers never collide).
  2. Announces its served queues, job types, and any recurring schedules. Registration is best-effort — a failure is logged and the worker keeps polling.
  3. Long-polls for jobs, requesting only as much work as it has free capacity for.
  4. For each job: emits one heartbeat immediately, dispatches to your handler with a JobContext, heartbeats on a cadence while the job runs, and acknowledges the outcome.
  5. On shutdown, stops polling, finishes the job in flight, and exits.

Heartbeats & progress

While a job runs the worker sends periodic heartbeats so the server knows the job is alive. Each heartbeat carries the latest progress you've reported via $ctx->reportProgress(). The cadence is max(10s, timeout / 3).

If the server replies to a heartbeat asking the job to cancel, the worker trips the job's cancellation handle (see below) and acknowledges the job as failed.

Cancellation & timeouts

Cancellation in PHP is cooperative. A handler must check $ctx->cancellationRequested() (or call $ctx->throwIfCancelled()) at safe points and unwind on its own. A handler that never yields cannot be interrupted from the outside and is bounded only by the server reclaiming the job after it goes silent.

A job is cancelled when any of these happen:

  • its configured timeout elapses,
  • the server asks for cancellation in a heartbeat response, or
  • the worker is shutting down.

Because acknowledgements are best-effort, jobs run at-least-once — if an ack is lost after the work completes, the same job is delivered again. Make handlers idempotent: guard externally-visible side effects on $ctx->jobId.

Graceful shutdown

On SIGTERM / SIGINT the worker stops accepting new work and finishes the job it is currently running before exiting — no job is abandoned. Give the process enough time to drain (match your supervisor's stop-wait to your longest job timeout) before it is force-killed.

Running a fleet

Run several worker processes to handle jobs concurrently. With a process supervisor, set the process count to your desired concurrency and forward SIGTERM for graceful shutdown. The starter sample ships a ready-to-adapt supervisor configuration.

Configuration

The worker reads FLARE_API_KEY, FLARE_BASE_URL, FLARE_QUEUES, and FLARE_POLL_INTERVAL from the environment, with everything else defaulted. See Worker options and Configuration precedence.

Reference