Error like the title, you can see at https://github.com/laravel/framework/issues/15696 And once again the laravel contributors said this was feature =)) https://github.com/ laravel / framework / issues / 15696 # issuecomment-250935907
In short, laravel will re-run the job after the job timeout no matter how many times you try to time the job. Read the laravel code you will see. Illuminate Queue Worker :: markJobAsFailedIfAlreadyExceedsMaxAttempts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /** * Mark the given job as failed if it has exceeded the maximum allowed attempts. * * This will likely be because the job previously exceeded a timeout. * * @param string $connectionName * @param IlluminateContractsQueueJob $job * @param int $maxTries * @return void */ protected function markJobAsFailedIfAlreadyExceedsMaxAttempts($connectionName, $job, $maxTries) { $maxTries = ! is_null($job->maxTries()) ? $job->maxTries() : $maxTries; $timeoutAt = $job->timeoutAt(); if ($timeoutAt && Carbon::now()->getTimestamp() <= $timeoutAt) { return; } if (! $timeoutAt && ($maxTries === 0 || $job->attempts() <= $maxTries)) { return; } $this->failJob($connectionName, $job, $e = new MaxAttemptsExceededException( $job->resolveName().' has been attempted too many times or run too long. The job may have previously timed out.' )); throw $e; } |
How to fix:
1. Set the option retry_after and restart queue every <retry_after time
Example: You set the job retry_after to 3600 seconds and restart queue every 2000 seconds.
2. Split job straight into multiple jobs.
If your job is doing a split job, create child jobs and dispatch child jobs in the parent job to avoid timeout.
3. Create 1 class extends from Illuminate Queue Worker class and override funtion markJobAsFailedIfAlreadyExceedsMaxAttempts
Simply delete the 3 lines of the other debt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /** * Mark the given job as failed if it has exceeded the maximum allowed attempts. * * This will likely be because the job previously exceeded a timeout. * * @param string $connectionName * @param IlluminateContractsQueueJob $job * @param int $maxTries * @return void */ protected function markJobAsFailedIfAlreadyExceedsMaxAttempts($connectionName, $job, $maxTries) { $maxTries = ! is_null($job->maxTries()) ? $job->maxTries() : $maxTries; $timeoutAt = $job->timeoutAt(); // if ($timeoutAt && Carbon::now()->getTimestamp() <= $timeoutAt) { // return; // } if (! $timeoutAt && ($maxTries === 0 || $job->attempts() <= $maxTries)) { return; } $this->failJob($connectionName, $job, $e = new MaxAttemptsExceededException( $job->resolveName().' has been attempted too many times or run too long. The job may have previously timed out.' )); throw $e; } |
And don’t forget to write a console command for the new worker class. Refer to the code in the vendor / laravel / framework / src / Illuminate / Queue / Console / WorkCommand.php file. Whoever finished writing, share it for me, I have not yet written =))