Skip to content

Commit 444141b

Browse files
[11.x] Allow SyncQueue to dispatch jobs after a transaction is committed (#48860)
* Fix after commit jobs using the sync queue * Additional test * Remove unnecessary check * formatting --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent 2acb803 commit 444141b

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

src/Illuminate/Queue/Queue.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ function () use ($payload, $queue, $delay, $callback, $job) {
326326
*/
327327
protected function shouldDispatchAfterCommit($job)
328328
{
329-
if (is_object($job) && $job instanceof ShouldQueueAfterCommit) {
329+
if ($job instanceof ShouldQueueAfterCommit) {
330330
return true;
331331
}
332332

src/Illuminate/Queue/SyncQueue.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ public function size($queue = null)
3434
* @throws \Throwable
3535
*/
3636
public function push($job, $data = '', $queue = null)
37+
{
38+
if ($this->shouldDispatchAfterCommit($job) &&
39+
$this->container->bound('db.transactions')) {
40+
return $this->container->make('db.transactions')->addCallback(
41+
fn () => $this->executeJob($job, $data, $queue)
42+
);
43+
}
44+
45+
return $this->executeJob($job, $data, $queue);
46+
}
47+
48+
/**
49+
* Execute a given job synchronously.
50+
*
51+
* @param string $job
52+
* @param mixed $data
53+
* @param string|null $queue
54+
* @return int
55+
*
56+
* @throws \Throwable
57+
*/
58+
protected function executeJob($job, $data = '', $queue = null)
3759
{
3860
$queueJob = $this->resolveJob($this->createPayload($job, $queue, $data), $queue);
3961

tests/Queue/QueueSyncQueueTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use Illuminate\Contracts\Events\Dispatcher;
88
use Illuminate\Contracts\Queue\QueueableEntity;
99
use Illuminate\Contracts\Queue\ShouldQueue;
10+
use Illuminate\Contracts\Queue\ShouldQueueAfterCommit;
11+
use Illuminate\Database\DatabaseTransactionsManager;
1012
use Illuminate\Queue\InteractsWithQueue;
1113
use Illuminate\Queue\Jobs\SyncJob;
1214
use Illuminate\Queue\SyncQueue;
@@ -77,6 +79,32 @@ public function testCreatesPayloadObject()
7779
$this->assertSame('extraValue', $e->getMessage());
7880
}
7981
}
82+
83+
public function testItAddsATransactionCallbackForAfterCommitJobs()
84+
{
85+
$sync = new SyncQueue;
86+
$container = new Container;
87+
$container->bind(\Illuminate\Contracts\Container\Container::class, \Illuminate\Container\Container::class);
88+
$transactionManager = m::mock(DatabaseTransactionsManager::class);
89+
$transactionManager->shouldReceive('addCallback')->once()->andReturn(null);
90+
$container->instance('db.transactions', $transactionManager);
91+
92+
$sync->setContainer($container);
93+
$sync->push(new SyncQueueAfterCommitJob());
94+
}
95+
96+
public function testItAddsATransactionCallbackForInterfaceBasedAfterCommitJobs()
97+
{
98+
$sync = new SyncQueue;
99+
$container = new Container;
100+
$container->bind(\Illuminate\Contracts\Container\Container::class, \Illuminate\Container\Container::class);
101+
$transactionManager = m::mock(DatabaseTransactionsManager::class);
102+
$transactionManager->shouldReceive('addCallback')->once()->andReturn(null);
103+
$container->instance('db.transactions', $transactionManager);
104+
105+
$sync->setContainer($container);
106+
$sync->push(new SyncQueueAfterCommitInterfaceJob());
107+
}
80108
}
81109

82110
class SyncQueueTestEntity implements QueueableEntity
@@ -134,3 +162,23 @@ public function getValueFromJob($key)
134162
return $payload['data'][$key] ?? null;
135163
}
136164
}
165+
166+
class SyncQueueAfterCommitJob
167+
{
168+
use InteractsWithQueue;
169+
170+
public $afterCommit = true;
171+
172+
public function handle()
173+
{
174+
}
175+
}
176+
177+
class SyncQueueAfterCommitInterfaceJob implements ShouldQueueAfterCommit
178+
{
179+
use InteractsWithQueue;
180+
181+
public function handle()
182+
{
183+
}
184+
}

0 commit comments

Comments
 (0)