Skip to content

Commit 00c9c7f

Browse files
[10.x] Add progress option to PendingBatch (#49273)
* Add `progress` option to pending batch * Invoke `progress` callback also on failure
1 parent 5654bdf commit 00c9c7f

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

src/Illuminate/Bus/Batch.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,14 @@ public function recordSuccessfulJob(string $jobId)
241241
{
242242
$counts = $this->decrementPendingJobs($jobId);
243243

244+
if ($this->hasProgressCallbacks()) {
245+
$batch = $this->fresh();
246+
247+
collect($this->options['progress'])->each(function ($handler) use ($batch) {
248+
$this->invokeHandlerCallback($handler, $batch);
249+
});
250+
}
251+
244252
if ($counts->pendingJobs === 0) {
245253
$this->repository->markAsFinished($this->id);
246254
}
@@ -283,6 +291,16 @@ public function finished()
283291
return ! is_null($this->finishedAt);
284292
}
285293

294+
/**
295+
* Determine if the batch has "progress" callbacks.
296+
*
297+
* @return bool
298+
*/
299+
public function hasProgressCallbacks()
300+
{
301+
return isset($this->options['progress']) && ! empty($this->options['progress']);
302+
}
303+
286304
/**
287305
* Determine if the batch has "success" callbacks.
288306
*
@@ -328,6 +346,14 @@ public function recordFailedJob(string $jobId, $e)
328346
$this->cancel();
329347
}
330348

349+
if ($this->hasProgressCallbacks() && $this->allowsFailures()) {
350+
$batch = $this->fresh();
351+
352+
collect($this->options['progress'])->each(function ($handler) use ($batch, $e) {
353+
$this->invokeHandlerCallback($handler, $batch, $e);
354+
});
355+
}
356+
331357
if ($counts->failedJobs === 1 && $this->hasCatchCallbacks()) {
332358
$batch = $this->fresh();
333359

src/Illuminate/Bus/PendingBatch.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,31 @@ public function add($jobs)
7474
return $this;
7575
}
7676

77+
/**
78+
* Add a callback to be executed after a job in the batch have executed successfully.
79+
*
80+
* @param callable $callback
81+
* @return $this
82+
*/
83+
public function progress($callback)
84+
{
85+
$this->options['progress'][] = $callback instanceof Closure
86+
? new SerializableClosure($callback)
87+
: $callback;
88+
89+
return $this;
90+
}
91+
92+
/**
93+
* Get the "progress" callbacks that have been registered with the pending batch.
94+
*
95+
* @return array
96+
*/
97+
public function progressCallbacks()
98+
{
99+
return $this->options['progress'] ?? [];
100+
}
101+
77102
/**
78103
* Add a callback to be executed after all jobs in the batch have executed successfully.
79104
*

tests/Bus/BusBatchTest.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ protected function setUp(): void
4040
$this->createSchema();
4141

4242
$_SERVER['__finally.count'] = 0;
43+
$_SERVER['__progress.count'] = 0;
4344
$_SERVER['__then.count'] = 0;
4445
$_SERVER['__catch.count'] = 0;
4546
}
@@ -72,7 +73,7 @@ public function createSchema()
7273
*/
7374
protected function tearDown(): void
7475
{
75-
unset($_SERVER['__finally.batch'], $_SERVER['__then.batch'], $_SERVER['__catch.batch'], $_SERVER['__catch.exception']);
76+
unset($_SERVER['__finally.batch'], $_SERVER['__progress.batch'], $_SERVER['__then.batch'], $_SERVER['__catch.batch'], $_SERVER['__catch.exception']);
7677

7778
$this->schema()->drop('job_batches');
7879

@@ -201,12 +202,14 @@ public function test_successful_jobs_can_be_recorded()
201202
$batch->recordSuccessfulJob('test-id');
202203

203204
$this->assertInstanceOf(Batch::class, $_SERVER['__finally.batch']);
205+
$this->assertInstanceOf(Batch::class, $_SERVER['__progress.batch']);
204206
$this->assertInstanceOf(Batch::class, $_SERVER['__then.batch']);
205207

206208
$batch = $batch->fresh();
207209
$this->assertEquals(0, $batch->pendingJobs);
208210
$this->assertTrue($batch->finished());
209211
$this->assertEquals(1, $_SERVER['__finally.count']);
212+
$this->assertEquals(2, $_SERVER['__progress.count']);
210213
$this->assertEquals(1, $_SERVER['__then.count']);
211214
}
212215

@@ -247,6 +250,7 @@ public function test_failed_jobs_can_be_recorded_while_not_allowing_failures()
247250
$this->assertTrue($batch->finished());
248251
$this->assertTrue($batch->cancelled());
249252
$this->assertEquals(1, $_SERVER['__finally.count']);
253+
$this->assertEquals(0, $_SERVER['__progress.count']);
250254
$this->assertEquals(1, $_SERVER['__catch.count']);
251255
$this->assertSame('Something went wrong.', $_SERVER['__catch.exception']->getMessage());
252256
}
@@ -288,6 +292,7 @@ public function test_failed_jobs_can_be_recorded_while_allowing_failures()
288292
$this->assertFalse($batch->finished());
289293
$this->assertFalse($batch->cancelled());
290294
$this->assertEquals(1, $_SERVER['__catch.count']);
295+
$this->assertEquals(2, $_SERVER['__progress.count']);
291296
$this->assertSame('Something went wrong.', $_SERVER['__catch.exception']->getMessage());
292297
}
293298

@@ -327,6 +332,11 @@ public function test_batch_state_can_be_inspected()
327332
$batch->finishedAt = now();
328333
$this->assertTrue($batch->finished());
329334

335+
$batch->options['progress'] = [];
336+
$this->assertFalse($batch->hasProgressCallbacks());
337+
$batch->options['progress'] = [1];
338+
$this->assertTrue($batch->hasProgressCallbacks());
339+
330340
$batch->options['then'] = [];
331341
$this->assertFalse($batch->hasThenCallbacks());
332342
$batch->options['then'] = [1];
@@ -463,6 +473,10 @@ protected function createTestBatch($queue, $allowFailures = false)
463473
$repository = new DatabaseBatchRepository(new BatchFactory($queue), DB::connection(), 'job_batches');
464474

465475
$pendingBatch = (new PendingBatch(new Container, collect()))
476+
->progress(function (Batch $batch) {
477+
$_SERVER['__progress.batch'] = $batch;
478+
$_SERVER['__progress.count']++;
479+
})
466480
->then(function (Batch $batch) {
467481
$_SERVER['__then.batch'] = $batch;
468482
$_SERVER['__then.count']++;

tests/Bus/BusPendingBatchTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,17 @@ public function test_pending_batch_may_be_configured_and_dispatched()
3737

3838
$pendingBatch = new PendingBatch($container, new Collection([$job]));
3939

40-
$pendingBatch = $pendingBatch->then(function () {
40+
$pendingBatch = $pendingBatch->progress(function () {
41+
//
42+
})->then(function () {
4143
//
4244
})->catch(function () {
4345
//
4446
})->allowFailures()->onConnection('test-connection')->onQueue('test-queue')->withOption('extra-option', 123);
4547

4648
$this->assertSame('test-connection', $pendingBatch->connection());
4749
$this->assertSame('test-queue', $pendingBatch->queue());
50+
$this->assertCount(1, $pendingBatch->progressCallbacks());
4851
$this->assertCount(1, $pendingBatch->thenCallbacks());
4952
$this->assertCount(1, $pendingBatch->catchCallbacks());
5053
$this->assertArrayHasKey('extra-option', $pendingBatch->options);

0 commit comments

Comments
 (0)