Skip to content

Commit 33e6739

Browse files
authored
[11.x] Avoid duplicate chain catch when nested batch fails on sync queue (#57322)
* avoid duplicate chain catch when nested batch fails on sync queue * Update Batch.php * Update Batch.php
1 parent b5be15d commit 33e6739

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

src/Illuminate/Bus/Batch.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Contracts\Queue\Factory as QueueFactory;
88
use Illuminate\Contracts\Support\Arrayable;
99
use Illuminate\Queue\CallQueuedClosure;
10+
use Illuminate\Queue\SyncQueue;
1011
use Illuminate\Support\Arr;
1112
use Illuminate\Support\Collection;
1213
use JsonSerializable;
@@ -184,15 +185,30 @@ public function add($jobs)
184185
return $job;
185186
});
186187

187-
$this->repository->transaction(function () use ($jobs, $count) {
188+
$queueConnection = $this->queue->connection($this->options['connection'] ?? null);
189+
190+
if ($queueConnection instanceof SyncQueue) {
188191
$this->repository->incrementTotalJobs($this->id, $count);
189192

190-
$this->queue->connection($this->options['connection'] ?? null)->bulk(
191-
$jobs->all(),
192-
$data = '',
193-
$this->options['queue'] ?? null
194-
);
195-
});
193+
try {
194+
$queueConnection->bulk(
195+
$jobs->all(),
196+
$data = '',
197+
$this->options['queue'] ?? null
198+
);
199+
} catch (Throwable $e) {
200+
}
201+
} else {
202+
$this->repository->transaction(function () use ($jobs, $count, $queueConnection) {
203+
$this->repository->incrementTotalJobs($this->id, $count);
204+
205+
$queueConnection->bulk(
206+
$jobs->all(),
207+
$data = '',
208+
$this->options['queue'] ?? null
209+
);
210+
});
211+
}
196212

197213
return $this->fresh();
198214
}

tests/Integration/Queue/JobChainingTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,24 @@ public function testChainBatchFailureNotAllowed()
484484
$this->assertEquals(['batch failed', 'chain failed'], JobRunRecorder::$failures);
485485
}
486486

487+
public function testChainBatchFailureNotAllowedOnSyncDoesNotDuplicateChainCatch()
488+
{
489+
config(['queue.default' => 'sync']);
490+
491+
JobRunRecorder::reset();
492+
493+
Bus::chain([
494+
new JobChainingNamedTestJob('c1'),
495+
Bus::batch([
496+
new JobChainingTestFailingBatchedJob('fb-sync'),
497+
])->allowFailures(false)->catch(fn () => JobRunRecorder::recordFailure('batch failed')),
498+
new JobChainingNamedTestJob('c2'),
499+
])->catch(fn () => JobRunRecorder::recordFailure('chain failed'))->dispatch();
500+
501+
$this->assertEquals(['batch failed', 'chain failed'], JobRunRecorder::$failures);
502+
$this->assertSame(1, collect(JobRunRecorder::$failures)->filter(fn ($m) => $m === 'chain failed')->count());
503+
}
504+
487505
public function testChainConditionable()
488506
{
489507
$chain = Bus::chain([])

0 commit comments

Comments
 (0)