Defining a payload job
A payload job is a class that implements Zeridion\Flare\Worker\Job and is
decorated with the #[FlareJob] attribute. The
worker calls its handle method with the decoded payload and a
JobContext.
<?php
use Zeridion\Flare\Worker\FlareJob;
use Zeridion\Flare\Worker\Job;
use Zeridion\Flare\Worker\JobContext;
#[FlareJob(queue: 'email', maxAttempts: 5, timeoutSeconds: 60)]
final class SendWelcomeEmail implements Job
{
public function handle(mixed $payload, JobContext $ctx): void
{
// at-least-once → make this idempotent
if ($this->alreadySent($ctx->jobId)) {
return;
}
$this->mailer->send($payload['email']);
$ctx->reportProgress(1.0);
}
}
Register it with the worker:
$worker->register(SendWelcomeEmail::class);
The handle method
The method name is fixed to handle. Its signature is always:
public function handle(mixed $payload, JobContext $ctx): void;
- Returning normally acknowledges the job as succeeded.
- Throwing any exception acknowledges the job as failed. The server then decides whether to retry (based on the attempt count) or dead-letter the job — the worker never makes that decision itself.
The payload
By default $payload is the decoded JSON straight off the wire — an
associative array for an object payload, a scalar, or null.
To receive a typed value object instead, set payloadClass on the attribute:
final class NewUserEvent
{
public string $userId = '';
public string $email = '';
}
#[FlareJob(name: 'SendWelcomeEmail', payloadClass: NewUserEvent::class)]
final class SendWelcomeEmail implements Job
{
public function handle(mixed $payload, JobContext $ctx): void
{
// $payload is a NewUserEvent
$this->mailer->send($payload->email);
}
}
The worker hydrates the class from the decoded array. If the class declares a
static fromArray(array): static factory it is used; otherwise public
properties are populated by name.
Idempotency
Jobs run at-least-once — if an acknowledgement is lost after the work
completes, the same job is delivered again. Guard externally-visible side
effects on $ctx->jobId so a redelivery is harmless:
public function handle(mixed $payload, JobContext $ctx): void
{
if ($this->ledger->hasProcessed($ctx->jobId)) {
return;
}
$this->charge($payload['amount']);
$this->ledger->markProcessed($ctx->jobId);
}
Dependencies
The worker constructs your job with a zero-argument new. To inject
collaborators, supply a factory when you register the job:
$worker->register(
SendWelcomeEmail::class,
fn () => new SendWelcomeEmail($mailer, $ledger),
);
The factory runs once per job execution.
See also
- The
#[FlareJob]attribute — queue, attempts, timeout, name, payload class - Job context — progress, cancellation, logging
- Recurring jobs