Removing Failed Jobs in Laravel Horizon, how is that done really? First you will notice you can restart jobs, but you cannot remove them. And if you had quite a few failed jobs like me during your testing you would want to get rid off them like me.
Flushing Horizon Queues
You can do this by flushing the queues from the command line. That is how it should work anyways. I Did a:
php artisan queue:flush
as suggested, but in my case things did not work out right away.
Table ‘forge.failed_jobs’ doesn’t exist
What I saw was an error:
Base table or view not found: 1146 Table 'forge.failed_jobs' doesn't exist (SQL: delete from `failed_jobs`)
It stated that the table failed jobs did not exist yet.
Failed Jobs Setup
Well, I decided to check how this was setup. So I opened:
config/queue.php
to check for the failed jobs setup. We had a default setup:
/* |-------------------------------------------------------------------------- | Failed Queue Jobs |-------------------------------------------------------------------------- | | These options configure the behavior of failed queue job logging so you | can control which database and table are used to store the jobs that | have failed. You may change them to any database / table you wish. | */ 'failed' => [ 'database' => env('DB_CONNECTION', 'mysql'), 'table' => 'failed_jobs', ], ];
And so we had not set up a failed jobs queue as of yet. The migration of that table was not done.
Current Failed Jobs Location
But like me you will be asking yourself. Where are the current failed jobs stored then?
when I checked the .env we had this default block
BROADCAST_DRIVER=log CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=redis
So the queue driver setup for us was redis. Only failed jobs were not set up for using Redis in app/config. Then I checked redis:
redis-cli <127.0.0.1:6379> INFO keyspace # Keyspace db0:keys=20,expires=15,avg_ttl=361086240
So there were 20 key value blocks. Now let’s see keys stored
127.0.0.1:6379> KEYS * 1) "horizon:5" 2) "horizon:9" 3) "horizon:3" 4) "horizon:12" 5) "horizon:7" 6) "horizon:job_id" 7) "horizon:1" 8) "horizon:supervisors" 9) "horizon:8" 10) "horizon:10" 11) "horizon:failed_jobs" 12) "horizon:6" 13) "horizon:monitor:time-to-clear" 14) "horizon:supervisor:xxx-prod-w-1-ZFbL:supervisor-1" 15) "horizon:last_snapshot_at" 16) "horizon:2" 17) "horizon:11" 18) "horizon:4" 19) "horizon:master:xxx-prod-w-1-ZFbL" 20) "horizon:masters"
I understood that scan is better though so for the same result use
redis-cli --scan --pattern '*'
Key eleven showed the failed_jobs. Now to list its content you first need to check its type:
type "horizon:failed_jobs" zset
It is a zset. To list there values I did:
zrange horizon:failed_jobs 0 -1 withscores 1) "12" 2) "-1532314417.1113" 3) "11" 4) "-1532254375.6877" 5) "10" 6) "-1532224555.5265999" 7) "9" 8) "-1532153045.0869" 9) "8" 10) "-1532152135.5623" 11) "7" 12) "-1532152078.1642001" 13) "6" 14) "-1532148754.2614999" 15) "5" 16) "-1532148589.0857" 17) "4" 18) "-1532148378.8659999" 19) "3" 20) "-1532147918.7011001" 21) "2" 22) "-1532147879.5788" 23) "1" 24) "-1531992162.2793"
To be continued …
Failed Jobs Table Migration
If you do want to set up this table in your MariaDB or MySQL database then you must create the migration* :
php artisan queue:failed-table
And finally run the migrations:
php artisan migrate
*source mingalevme at laravel.io at this thread.
That should do the trick.
Driver Change
If you however just want to continue using redis, also for failed jobs as you may have like us you will probably need to change the driver. More information on that will follow.
Medis & Command Line
Thanks to Stef I found a way to more easily remove keys with Medis and using the command line though:
Stef Blokdijk mentioned at https://github.com/laravel/horizon/issues/122#issuecomment-412394779 that you can use Medis to remove the keys as well. It is a Redis GUI Tool. He also mentioned some manual option he found on SO to remove failed jobs:
I manually deleted the horizon:failed_jobs key.
Then I deleted all the other failed jobs with this Redis CLI command. (source: stackoverflow)
EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 horizon:failed:*