Queue
Job dispatching, worker processing, timeouts, and queue events for the VelvetCMS Core queue stack.
Namespaces: VelvetCMS\Queue\* · Container: queue, queue.worker
VelvetCMS keeps the queue stack small: a Job base class, QueueManager, database/sync drivers, and queue:work for daemon processing.
Container services #
| Name | Class | Role |
|---|---|---|
queue |
VelvetCMS\Queue\QueueManager |
Dispatch, pop, lifecycle hooks |
queue.worker |
VelvetCMS\Queue\Worker |
Daemon loop |
app('queue')->dispatch(new SendDigestJob($userId))->send();
Defining a job #
Extend VelvetCMS\Queue\Job and implement handle():
final class SendDigestJob extends \VelvetCMS\Queue\Job
{
public function __construct(
private readonly int $userId,
) {}
public function handle(): void
{
// Reload fresh state here (payloads should prefer IDs, not ORM objects).
}
public function failed(\Throwable $exception): void
{
// Optional: called when attempts are exhausted
}
}
Serialized state: serialize() captures constructor-injected properties that are scalar, array, or null. Meta (tries, retryAfter, timeout, etc.) is stored separately and restored in deserialize().
| Property | Default | Notes |
|---|---|---|
$tries |
3 |
After this many failed attempts the job moves to failed_jobs |
$retryAfter |
60 |
Delay when re-queued after a soft failure |
$timeout |
60 |
Honoured by the worker when pcntl alarms are available |
$queue |
'default' |
Logical queue name |
$delay |
null |
Initial delay in seconds when pushed |
Job helpers: onQueue(string $queue), delay(?int $seconds = null, ?\DateTimeInterface $until = null).
PendingDispatch chaining uses the same delay() overloads plus optional minutes:
delay(?int $seconds = null, ?int $minutes = null, ?\DateTimeInterface $until = null).
Dispatching #
$qm = app('queue');
// Async (returns driver job id)
$id = $qm->dispatch(new SendDigestJob(42))
->onQueue('mail')
->delay(minutes: 5)
->send();
// Same process
$qm->dispatchNow(new SendDigestJob(42));
VelvetCMS\Queue\PendingDispatch:
onQueue(string $queue): staticdelay(?int $seconds = null, ?int $minutes = null, ?\DateTimeInterface $until = null): staticsend(): stringsendNow(): void: runshandle()synchronously; still assigns a syntheticsync-*id
Worker #
./velvet queue:work [--queue=] [--sleep=] [--memory=] [--max-jobs=] [--timeout=] [--retry-after=]
Defaults come from Queue configuration. When job execution exceeds Job::$timeout and the host supports pcntl + SIGALRM, the worker throws VelvetCMS\Exceptions\JobTimeoutException and normal retry / fail rules apply.
Events #
| Event | Payload |
|---|---|
queue.job.processing |
Job instance |
queue.job.processed |
Job instance |
queue.job.released |
Job instance |
queue.job.failed |
array{job: Job, exception: \Throwable} |
Helper #
queue()->dispatch(new SendDigestJob(1))->send();
See Standard events.