Laravel 5.1 failed queued jobs fails on failed() method, prevents queue failure event handler from being called -
i testing queue functions in laravel 5.1. can make jobs queue in db table, called jobs, , can them run successfully. created queue failure table called failed_jobs. test it, inside jobs table manipulate payload data make fail run queue worker daemon so, put job in failed_jobs table after 1 failed attempt:
php artisan queue:work --daemon --tries=1 --queue=myqueue
when job fails put failed_jobs table expected.
fyi have set things laravel 5.1 docs recommend:
http://laravel.com/docs/5.1/queues#dealing-with-failed-jobs
i have tried registering queue failure event in appserviceprovider's boot() method outlined in docs:
queue::failing(function ($connection, $job, $data) { log::error('job failed!'); });
i have tried failed() method inside actual job scripts so:
/** * handle job failure. * * @return void */ public function failed() { log::error('failed!'); }
either way, neither of these events triggered when queued job fails. see nothing in logs except exception stack trace made occur on purpose. laravel 5.1 have bug here or missing something?
update:
i have done more research. when queue job failure occurs, logic handling failure in vendor/laravel/framework/src/illuminate/queue/worker.php:
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]; }
what happens failed() function never executes , prevents next function, raisedfailedjobevent() being called. it's if script silently halts when failed() called. if reverse order of these lines, can raisefailedjobevent() fire , if register queue event handler in eventserviceprovider.php or appserviceprovider.php, can verify gets fired , can handle event. unfortunately, having failed() before raisefailedjobevent() prevents event ever occurring.
update:
the problem seems stem how make fail. if deliberately corrupt data in job queue table, failed() method never gets called. there stack trace in logs:
stack trace: #0 [internal function]: illuminate\foundation\bootstrap\handleexceptions->handleerror(8, 'unserialize():
if go vendor/laravel/framework/src/illuminate/queue/worker.php , force fail every time runs (in exception-less way of course), failure() gets called. problem, obviously, how know how queue behave in real-world failure? if corrupt db data causes failure yet prevents failure() being called, no good. if there actual corruption of db queue data in real world?
try out conversation graham @ https://github.com/laravel/framework/issues/9799
in end elegant solution find the failed() method trigger on job class add below boot() method of eventserviceprovider.php. catching full fail event fired , digging out command/job , unserializing call failed() method.
queue::failing(function($connection, $job, $data) { $command = (unserialize($data['data']['command'])); $command->failed(); });
Comments
Post a Comment