phplaravelredislaravel-queuelaravel-jobs

Laravel delete job once it fails


I have a job that times out and once it fails it dispatches another one just like itself so that it can run infinitely and without overlapping. However the job that fails stays in the queue and gets re-tried so I eventually have more than one job running which breaks the whole purpose.

Here is how I handle the failing of the job:

use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

public function handle()
{
    //infinite websocket listening loop
}

public function failed(Exception $exception)
{
    $this::dispatch()->onQueue('long-queue');
    $this->delete();
}

$this->delete() comes from InteractsWithQueue trait. What am I doing wrong?

Edit: I am using horizon for running the jobs, here is the configuration for the custom queue set in config/horizon.php

'supervisor-long' => [
    'connection' => 'redis-long',
    'queue' => ['long-queue'],
    'balance' => 'simple',
    'processes' => 3,
    'tries' => 1,
    'timeout' => 3600,
],

The job that I am dispatching is creating a Thruway client to connect to a web-socket server and subscribe to a channel for updates so I want to run this job forever, but only run one instance of this job at any time. That is why I want it to run once without any tries and once it times out to dispatch another instance that will run and the loop will continue. I couldn't think of a better way to achieve this, is there another way to do this better?


Solution

  • Turns out that my jobs were not failing so the failed() method was not getting executed. Even if you set tries to tries => 1 within your config/horizon.php file, you need to set the retry_after value to 0 within your config/queue.php file so that the job fails just after it times out. This way your failed() methods gets called immediately. Below you can find the final forms of my config files.

    config/queue.php:

    'redis-long' => [
        'driver' => 'redis',
        'connection' => 'default',
        'queue' => 'long-queue',
        'retry_after' => 0,
        'block_for' => null,
    ],
    

    config/horizon.php:

    'supervisor-long' => [
        'connection' => 'redis-long',
        'queue' => ['long-queue'],
        'balance' => 'simple',
        'processes' => 1,
        'tries' => 1,
        'timeout' => 3600,
    ],