Laravel Horizon is a fantastic tool, which I use in all my projects for my queues.
If you are using Horizon, I’m sure you’ve noticed that there are 2 separate places for the failed jobs: in database `failed_jobs_table` and and in Redis. The failed jobs you see in your Horizon dashboard are the ones in Redis.
When something goes wrong
It’s inevitable to have everything in perfect harmony, so it happens! Jobs do fail in your queues.
Let’s say a 3rd party api in our job went down. Now we have 100 failed jobs in our Horizon dashboard as well as in failed_jobs_table in database.
Long story short, now we need to retry them.
Option one is to click the retry button in Horizon dashboard one-by-one. 😱
However, there is a nicer way!
If you try running this command, it gives you failed jobs in your Redis (so Horizon)
use use Laravel\Horizon\Contracts\JobRepository;$failedJobs = app(JobRepository::class)->getFailed();
Nice! Now that we got failed jobs, we can just retry them through Horizon’s RetryFailedJob class:
use Laravel\Horizon\Jobs\RetryFailedJob;dispatch(new RetryFailedJob($uuid));
And easy enough, you can delete your retried jobs in your database for having redis & database failed jobs in sync;
Sweet! Now we have all the parts we need of the puzzle.
Let’s bring them together:
I love to create an artisan command for this task
php artisan make:command RetryFailedJobsViaHorizon
That’s it really; and you can expand it as you wish!
Two ways I improved it are: 1) Added “job-name” argument to run only specific jobs; 2) Added “date” argument to run failed jobs on specific date.
Hope you enjoyed this post. If you did, please give me a 👏 and if you want to see more of these kind of posts, don’t forget to follow me 😊.