Skip to content

Commit b27f967

Browse files
cgrama-actaylorotwell
authored andcommitted
Fix job release on exception
Without this change the worker does not account for changes to the job state done in the JobExceptionOccurred event listener except for when the job was deleted. If there is a need to release the job back onto the queue with a different delay than the one set on the worker, the job would be released with the worker delay. If the job needs to be failed by the JobExceptionOccurred event listener that is not possible and will be ignored by the worker. A job should not be released back onto the queue if the job has been handled in the JobExceptionOccurred event listener by failing, deleting or releasing it with a specific delay. The event listener should have full controller over what happens with the job for what concerns deleting, failing and deleting the job.
1 parent 3687363 commit b27f967

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

src/Illuminate/Queue/Worker.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,9 @@ protected function handleJobException($connectionName, $job, WorkerOptions $opti
328328
// If we catch an exception, we will attempt to release the job back onto the queue
329329
// so it is not lost entirely. This'll let the job be retried at a later time by
330330
// another listener (or this same one). We will re-throw this exception after.
331-
if (! $job->isDeleted()) {
331+
// Do not release the job back onto the queue if the job is either deleted, failed
332+
// or if the job has already been released from the JobExceptionOccurred event listener.
333+
if (! ($job->isReleased() || $job->isDeleted() || $job->hasFailed())) {
332334
$job->release($options->delay);
333335
}
334336
}

tests/Queue/QueueWorkerTest.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,11 @@ class WorkerFakeJob
257257
public $callback;
258258
public $deleted = false;
259259
public $releaseAfter;
260+
public $released = false;
260261
public $maxTries;
261262
public $attempts = 0;
262263
public $failedWith;
264+
public $failed = false;
263265
public $connectionName;
264266

265267
public function __construct($callback = null)
@@ -296,24 +298,38 @@ public function isDeleted()
296298

297299
public function release($delay)
298300
{
301+
$this->released = true;
302+
299303
$this->releaseAfter = $delay;
300304
}
301305

306+
public function isReleased()
307+
{
308+
return $this->released;
309+
}
310+
302311
public function attempts()
303312
{
304313
return $this->attempts;
305314
}
306315

307316
public function markAsFailed()
308317
{
309-
//
318+
$this->failed = true;
310319
}
311320

312321
public function failed($e)
313322
{
323+
$this->markAsFailed();
324+
314325
$this->failedWith = $e;
315326
}
316327

328+
public function hasFailed()
329+
{
330+
return $this->failed;
331+
}
332+
317333
public function setConnectionName($name)
318334
{
319335
$this->connectionName = $name;

0 commit comments

Comments
 (0)