Kinetis Queue Failed Jobs 1.0: Keep the Jobs Your Worker Gives Up On#
When a job fails on its last attempt, the queue worker logs it and
deletes it. Until now that was the end of it: if the failure came from
a bug you have since fixed, or from an API that was down for an hour,
the job was gone. kinetis/queue-failed-jobs 1.0.0 keeps those jobs
in a database table, so you can look at them and run them again.
Getting started#
Install the package:
composer require kinetis/queue-failed-jobs
Copy the migration stub for your database from
vendor/kinetis/queue-failed-jobs/resources/migrations/ into your
migrations/ directory, then run vendor/bin/kinetis migrate. That’s
all. Once the package is installed, the worker records failed jobs.
There is no setting to turn it on.
It works with every queue backend: Redis, SQL, SQS and RabbitMQ. The
records go to MySQL or Postgres through kinetis/database-bridge,
whatever backend the queue itself uses. To keep them on a database
other than your default one, set FAILED_JOBS_DB_CONNECTION_NAME.
Four commands#
vendor/bin/kinetis queue:failed --queue=mail
vendor/bin/kinetis queue:retry 3f9c0b2a64d14e8f9a0c51d7e2b46a18
vendor/bin/kinetis queue:retry --all
vendor/bin/kinetis queue:forget 3f9c0b2a64d14e8f9a0c51d7e2b46a18
vendor/bin/kinetis queue:prune --hours=168
queue:failedlists the records, oldest first.queue:retrypushes a job back onto the queue it failed on, then deletes its record. If the push fails, the record stays and the command exits 1.queue:forgetdeletes a record without retrying the job.queue:prunedeletes old records. Nothing is pruned automatically.
Never lost, sometimes twice#
The worker writes the record before it asks the queue backend to delete the job. If the write fails, the worker stops and the backend keeps the job, so a job you gave up on is never lost.
The flip side is that a crash at the wrong moment can leave a job both recorded and still on the queue, and the next delivery can record it again. This is the same at-least-once guarantee the queue already gives, so a handler that can safely run twice can also be safely retried.
Things to know#
Arguments are stored in full. A retry rebuilds the job from its arguments, so the table holds
#[Sensitive]values too. Protect it the way you protect the queue’s own storage.queue:failedprints sensitive values as[redacted].The worker depends on the failed-jobs database. If that database refuses a write,
queue:workstops, and the job stays on its queue.Some failures are never recorded. A job that crashes its worker process never reaches the failure path. On SQS, a redrive policy covers that case.
The failed jobs guide covers the details.
Upgrading#
Install kinetis/queue-failed-jobs 1.0.0. It requires kinetis/queue
1.8.0, the release that adds the hook the worker records through.
JobFailedPermanently now carries the record’s ID as failedJobId.