From e9f1d38d41bf0cd048957f7234c7abf060673439 Mon Sep 17 00:00:00 2001 From: Rodrigo Pedra Brum Date: Sat, 25 Jun 2022 11:02:00 -0300 Subject: [PATCH 1/2] prevent double throwing chained exception on sync queue --- src/Illuminate/Queue/SyncQueue.php | 18 +++++-- tests/Integration/Queue/JobChainingTest.php | 54 +++++++++++++++++++-- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/Illuminate/Queue/SyncQueue.php b/src/Illuminate/Queue/SyncQueue.php index 33638c213a66..c88e6f4cafa1 100755 --- a/src/Illuminate/Queue/SyncQueue.php +++ b/src/Illuminate/Queue/SyncQueue.php @@ -12,6 +12,8 @@ class SyncQueue extends Queue implements QueueContract { + protected $jobsCount = 0; + /** * Get the size of the queue. * @@ -37,6 +39,8 @@ public function push($job, $data = '', $queue = null) { $queueJob = $this->resolveJob($this->createPayload($job, $queue, $data), $queue); + $this->jobsCount++; + try { $this->raiseBeforeJobEvent($queueJob); @@ -113,11 +117,19 @@ protected function raiseExceptionOccurredJobEvent(Job $job, Throwable $e) */ protected function handleException(Job $queueJob, Throwable $e) { - $this->raiseExceptionOccurredJobEvent($queueJob, $e); + static $isGuarded = false; + + if ($isGuarded) { + $isGuarded = false; + } else { + $isGuarded = $this->jobsCount > 1; - $queueJob->fail($e); + $this->raiseExceptionOccurredJobEvent($queueJob, $e); - throw $e; + $queueJob->fail($e); + + throw $e; + } } /** diff --git a/tests/Integration/Queue/JobChainingTest.php b/tests/Integration/Queue/JobChainingTest.php index b0ad447768f3..382211e4ed4d 100644 --- a/tests/Integration/Queue/JobChainingTest.php +++ b/tests/Integration/Queue/JobChainingTest.php @@ -12,7 +12,7 @@ class JobChainingTest extends TestCase { - public static $catchCallbackRan = false; + public static $catchCallbackCount = 0; protected function getEnvironmentSetUp($app) { @@ -30,7 +30,6 @@ protected function tearDown(): void JobChainingTestFirstJob::$ran = false; JobChainingTestSecondJob::$ran = false; JobChainingTestThirdJob::$ran = false; - static::$catchCallbackRan = false; } public function testJobsCanBeChainedOnSuccess() @@ -148,19 +147,56 @@ public function testThirdJobIsNotFiredIfSecondFails() public function testCatchCallbackIsCalledOnFailure() { + self::$catchCallbackCount = 0; + Bus::chain([ new JobChainingTestFirstJob, new JobChainingTestFailingJob, new JobChainingTestSecondJob, ])->catch(static function () { - self::$catchCallbackRan = true; + self::$catchCallbackCount++; })->dispatch(); $this->assertTrue(JobChainingTestFirstJob::$ran); - $this->assertTrue(static::$catchCallbackRan); + $this->assertSame(1, static::$catchCallbackCount); $this->assertFalse(JobChainingTestSecondJob::$ran); } + public function testCatchCallbackIsCalledOnceOnSyncQueue() + { + self::$catchCallbackCount = 0; + + try { + Bus::chain([ + new JobChainingTestFirstJob(), + new JobChainingTestThrowJob(), + new JobChainingTestSecondJob(), + ])->catch(function () { + self::$catchCallbackCount++; + })->onConnection('sync')->dispatch(); + } finally { + $this->assertTrue(JobChainingTestFirstJob::$ran); + $this->assertSame(1, static::$catchCallbackCount); + $this->assertFalse(JobChainingTestSecondJob::$ran); + } + + self::$catchCallbackCount = 0; + + try { + Bus::chain([ + new JobChainingTestFirstJob(), + new JobChainingTestThrowJob(), + new JobChainingTestSecondJob(), + ])->catch(function () { + self::$catchCallbackCount++; + })->onConnection('sync')->dispatch(); + } finally { + $this->assertTrue(JobChainingTestFirstJob::$ran); + $this->assertSame(1, static::$catchCallbackCount); + $this->assertFalse(JobChainingTestSecondJob::$ran); + } + } + public function testChainJobsUseSameConfig() { JobChainingTestFirstJob::dispatch()->allOnQueue('some_queue')->allOnConnection('sync1')->chain([ @@ -293,3 +329,13 @@ public function handle() $this->fail(); } } + +class JobChainingTestThrowJob implements ShouldQueue +{ + use Dispatchable, InteractsWithQueue, Queueable; + + public function handle() + { + throw new \Exception(); + } +} From d7e7b94e03d355fc91115092f0b970ec537728f6 Mon Sep 17 00:00:00 2001 From: Rodrigo Pedra Brum Date: Mon, 27 Jun 2022 13:50:46 -0300 Subject: [PATCH 2/2] decrease job count after processing --- src/Illuminate/Queue/SyncQueue.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Illuminate/Queue/SyncQueue.php b/src/Illuminate/Queue/SyncQueue.php index c88e6f4cafa1..0edd639c9e5c 100755 --- a/src/Illuminate/Queue/SyncQueue.php +++ b/src/Illuminate/Queue/SyncQueue.php @@ -49,6 +49,8 @@ public function push($job, $data = '', $queue = null) $this->raiseAfterJobEvent($queueJob); } catch (Throwable $e) { $this->handleException($queueJob, $e); + } finally { + $this->jobsCount--; } return 0;