Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/Illuminate/Queue/Events/QueueForwarded.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Illuminate\Queue\Events;

class QueueForwarded
{
/**
* Create a new event instance.
*
* @param string|null $connectionName The queue connection the queue was forwarded on.
* @param string $from The queue that was forwarded.
* @param string $to The queue that was forwarded to.
*/
public function __construct(
public ?string $connectionName,
public string $from,
public string $to,
) {
}
}
28 changes: 28 additions & 0 deletions src/Illuminate/Queue/Queue.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Illuminate\Queue\Attributes\Tries;
use Illuminate\Queue\Events\JobQueued;
use Illuminate\Queue\Events\JobQueueing;
use Illuminate\Queue\Events\QueueForwarded;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\InteractsWithTime;
Expand All @@ -29,6 +30,8 @@
use RuntimeException;
use Throwable;

use function Illuminate\Support\enum_value;

abstract class Queue
{
use InteractsWithTime, ReadsQueueAttributes, ResolvesQueueRoutes;
Expand Down Expand Up @@ -372,6 +375,8 @@ protected function enqueueUsing($job, $payload, $queue, $delay, $callback)

return $this->container->make('db.transactions')->addCallback(
function () use ($queue, $job, $payload, $delay, $callback) {
$this->raiseQueueForwardedEvent($queue);

$this->raiseJobQueueingEvent($queue, $job, $payload, $delay);

return tap($callback($payload, $queue, $delay), function ($jobId) use ($queue, $job, $payload, $delay) {
Expand All @@ -381,6 +386,8 @@ function () use ($queue, $job, $payload, $delay, $callback) {
);
}

$this->raiseQueueForwardedEvent($queue);

$this->raiseJobQueueingEvent($queue, $job, $payload, $delay);

return tap($callback($payload, $queue, $delay), function ($jobId) use ($queue, $job, $payload, $delay) {
Expand Down Expand Up @@ -487,6 +494,27 @@ protected function raiseJobQueuedEvent($queue, $jobId, $job, $payload, $delay)
}
}

/**
* Raise the queue forwarded event.
*
* @param \UnitEnum|string|null $queue
* @return void
*/
protected function raiseQueueForwardedEvent($queue)
{
$from = enum_value($queue) ?: ($this->default ?? null);

if (is_null($from)) {
return;
}

$to = $this->resolveQueue($from);

if ($to !== $from && $this->container->bound('events')) {
$this->container['events']->dispatch(new QueueForwarded($this->connectionName, $from, $to));
}
}

/**
* Get the routed queue name for the given queue.
*
Expand Down
2 changes: 2 additions & 0 deletions src/Illuminate/Queue/SqsQueue.php
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ protected function prepareBatchMessages(array $jobs, $data, $queue)
*/
protected function sendBatchedMessages(array $messages, $queue)
{
$this->raiseQueueForwardedEvent($queue);

$entries = [];

foreach ($messages as $id => $message) {
Expand Down
26 changes: 26 additions & 0 deletions tests/Queue/QueueDatabaseQueueIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
use Illuminate\Queue\DatabaseQueue;
use Illuminate\Queue\Events\JobQueued;
use Illuminate\Queue\Events\JobQueueing;
use Illuminate\Queue\Events\QueueForwarded;
use Illuminate\Queue\Queue;
use Illuminate\Queue\QueueRoutes;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -288,4 +290,28 @@ public function testJobPayloadIsAvailableOnEvents()
$this->assertIsArray($jobQueuedEvent->payload());
$this->assertSame('expected-job-uuid', $jobQueuedEvent->payload()['uuid']);
}

public function testQueueForwardedEventIsDispatchedWhenQueueIsForwarded()
{
$queueForwardedEvent = null;

Container::setInstance($this->container);

$this->container->instance('queue.routes', tap(new QueueRoutes, function ($routes) {
$routes->forward('jobs', 'processing');
}));

$this->container['events']->listen(function (QueueForwarded $e) use (&$queueForwardedEvent) {
$queueForwardedEvent = $e;
});

$this->queue->push('MyJob', [
'laravel' => 'Framework',
], 'jobs');

$this->assertSame('jobs', $queueForwardedEvent->from);
$this->assertSame('processing', $queueForwardedEvent->to);

Container::setInstance(null);
}
}
32 changes: 32 additions & 0 deletions tests/Queue/QueueSqsQueueTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Queue\Events\QueueForwarded;
use Illuminate\Queue\Jobs\SqsJob;
use Illuminate\Queue\QueueRoutes;
use Illuminate\Queue\SqsQueue;
Expand Down Expand Up @@ -1122,6 +1123,37 @@ public function testBulkRaisesQueueingAndQueuedEventsForEachJob()
$this->assertSame(['mid-0', 'mid-1'], array_map(fn ($e) => $e->id, array_values($queuedEvents)));
}

public function testBulkRaisesQueueForwardedEventOnceForTheBatch()
{
Container::setInstance($container = new Container);
$routes = new QueueRoutes;
$routes->forward($this->queueName, 'processing', 'sqs');
$container->instance('queue.routes', $routes);

$forwarded = [];
$events = Mockery::mock(\Illuminate\Contracts\Events\Dispatcher::class);
$events->allows('dispatch')->andReturnUsing(function ($event) use (&$forwarded) {
if ($event instanceof QueueForwarded) {
$forwarded[] = $event;
}
});
$container->instance('events', $events);

$queue = new SqsQueue($this->sqs, $this->queueName, $this->prefix);
$queue->setContainer($container);
$queue->setConnectionName('sqs');

$this->sqs->expects('sendMessageBatch')->andReturn(new Result(['Successful' => [], 'Failed' => []]));

$queue->bulk(['a', 'b'], 'data', $this->queueName);

$this->assertCount(1, $forwarded);
$this->assertSame($this->queueName, $forwarded[0]->from);
$this->assertSame('processing', $forwarded[0]->to);

Container::setInstance(null);
}

public function testBulkHonoursPerJobDelay()
{
$jobA = new FakeSqsJob;
Expand Down
Loading