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?
The reason why failed is not executed, it is only triggered when a job exceeds it's maximum tries. The flow looks something like this.
$job->dispatch(); // try 1
// times out
// retries on try 2 now
// times out
// retries on try 3 now
// max attempt is hit and MaxAttempt exception is thrown
// failed is called
This logic is changed if your job actually crashes, this example is only when it runs indefinitely. Where the logic is handled.
On your queue definition in config/horizon.php you can define tries.
'my-short-queue' => [
'connection' => 'redis',
'queue' => ['my-short-queue'],
'balance' => 'simple',
'processes' => 1,
'tries' => 1,
]
Found you can actually do this in the failed
method in a queued job:
/**
* Handle the failing job.
*
* @param Exception $ex
*
* @return void
*/
public function failed(Exception $ex)
{
$this->delete();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With