How can I create delays between failed Queued Job

2019-02-13 08:04发布

问题:

I have a queued job in Laravel that fails from time to time because of an external API failing due to high load. The problem is that my choices appear to be to have the Laravel Queue continue to hammer the API with requests until it succeeds or tell it to stop after X number of requests.

Is there any way for me to, based on how the job fails, tell it to try again in 5 minutes instead of continuing to hammer away?

I want to use the built in queue handler, but the retry functionality doesn't appear to be built to handle real life scenarios of failure. I would think that many reasons for failing a job wouldn't be solved by immediately trying again.

回答1:

What you can do is something like this:

// app/Jobs/ExampleJob.php
namespace App\Jobs;

class ExampleJob extends Job
{
    use \Illuminate\Queue\InteractsWithQueue;

    public function handle()
    {
        try {
            // Do stuff that might fail
        } catch(AnException $e) {
            // Example where you might want to retry

            if ($this->attempts() < 3) {
                $delayInSeconds = 5 * 60;
                $this->release($delayInSeconds);
            }
        } catch(AnotherException $e) {
            // Example where you don't want to retry
            $this->delete();
        }
    }
}

Please note that you do not have to do this with exceptions, you can also just check the result from your actions and decide from there.



回答2:

You could manually release the job using the Illuminate\Queue\InteractsWithQueue method

$this->release(10);

The argument will define the amount of seconds until the job is available again.

Check the section Manually Releasing Jobs in the official documentation for version 5.1.