I am testing queue functions in Laravel 5.1. I can queue jobs in my db table called jobs, and I can get them to work successfully. I also created a queue failure table called fail_jobs. To verify this, inside the job table I manipulate the payload data so that it does not work, so I start the working queue daemon so that it puts the job in the failed_jobs table after one unsuccessful attempt:
php artisan queue:work --daemon --tries=1 --queue=myqueue
When a job fails, it is immediately placed in the fail_jobs table, as expected.
FYI I installed things the same way the Laravel 5.1 docs recommend:
http://laravel.com/docs/5.1/queues#dealing-with-failed-jobs
I tried to register the queue failure event in the AppServiceProvider () load method, as described in the docs:
Queue::failing(function ($connection, $job, $data) { Log::error('Job failed!'); });
I also tried the failed () method inside the work scripts:
public function failed() { Log::error('failed!'); }
In any case, none of these events are triggered when an unsuccessful job is in the queue. I do not see anything in the logs, except that I do the exception stack trace specifically. Does Laravel 5.1 have an error here, or am I missing something?
UPDATE:
I did some more research. When a queue job fails, the logic for handling this failure is in the vendor / laravel / framework / src / Illuminate / Queue / Worker.php file:
protected function logFailedJob($connection, Job $job) { if ($this->failer) { $this->failer->log($connection, $job->getQueue(), $job->getRawBody()); $job->delete(); $job->failed(); $this->raiseFailedJobEvent($connection, $job); } return ['job' => $job, 'failed' => true]; }
It happens that the fail () function is never executed and prevents the next function from being called by the raiseFailedJobEvent () function. As if the script is silently stopping when fail () is called. Now, if I reverse the order of these lines, I can run raiseFailedJobEvent (), and if I register the queue event handler in EventServiceProvider.php or AppServiceProvider.php, I can verify that it is running and I can successfully handle the event. Unfortunately, crashing () before raiseFailedJobEvent () prevents this event from ever occurring.
UPDATE:
The problem seems to be related to how I make this fail. If I intentionally distort the data in the job queue table, the fail () method will never be called. There is a stack trace in the logs:
Stack trace:
If I really go to the /laravel/framework/src/Illuminate/Queue/Worker.php provider and make it fail every time it starts (of course, without exception), then the fail () function is called. The problem, obviously, is how can I find out how this queue will behave in a real failure? If the damaged db data fails, it still prevents the fail () function from being called, this is not good. What to do if db queue data actually gets corrupted in the real world?