Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ CHANGELOG

* Allow SQS to handle its own retry/DLQ
* Add `retry_delay` option to configure the delay between retries when using SQS retry/DLQ handling
* Add SQS fair queues support

7.3
---
Expand Down
30 changes: 30 additions & 0 deletions src/Symfony/Component/Messenger/Bridge/AmazonSqs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,40 @@ Amazon SQS Messenger

Provides Amazon SQS integration for Symfony Messenger.

Available stamps
----------------

- `Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsFifoStamp`
- Use with FIFO queues (queue name ends with `.fifo`).
- Set per-message "Message group ID" and optional "Message deduplication ID".
- If both FIFO and FairQueue stamps are present, FIFO takes precedence.

- `Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsFairQueueStamp`
- Enables fair processing on standard queues by setting `MessageGroupId`.
- Use a tenant/group identifier to balance processing across groups.
- Has no effect on FIFO queues. Ignored when FIFO stamp is present.

- `Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsXrayTraceHeaderStamp`
- Adds an AWS X-Ray `TraceId` to the outgoing SQS message attributes.

- `Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsReceivedStamp`
- Carries the SQS `ReceiptHandle`/message identifier for received messages.

Notes
-----

- Middleware: `Symfony\Component\Messenger\Bridge\AmazonSqs\Middleware\AddFifoStampMiddleware`
- If the message implements `MessageDeduplicationAwareInterface`, the middleware adds `AmazonSqsFifoStamp` and sets the deduplication ID.
- If the message implements `MessageGroupAwareInterface`, the middleware sets the group ID on the stamp.

- FIFO queues do not support per-message delay. Configure retry strategy with `delay: 0`.

Resources
---------

* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)
in the [main Symfony repository](https://github.com/symfony/symfony)
* [AWS SQS FIFO queues](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-fifo-queues.html)
* [AWS SQS Fair queues](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-fair-queues.html)
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use PHPUnit\Framework\TestCase;
use Symfony\Component\Messenger\Bridge\AmazonSqs\Tests\Fixtures\DummyMessage;
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsFairQueueStamp;
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsFifoStamp;
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsSender;
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsXrayTraceHeaderStamp;
Expand Down Expand Up @@ -87,4 +88,41 @@ public function testSendEncodeBodyToRespectAmazonRequirements()
$sender = new AmazonSqsSender($connection, $serializer);
$sender->send($envelope);
}

public function testSendWithAmazonSqsFairQueueStamp()
{
$envelope = (new Envelope(new DummyMessage('Oy')))
->with($stamp = new AmazonSqsFairQueueStamp('tenant-123'));

$encoded = ['body' => '...', 'headers' => ['type' => DummyMessage::class]];

$connection = $this->createMock(Connection::class);
$connection->expects($this->once())->method('send')
->with($encoded['body'], $encoded['headers'], 0, $stamp->getMessageGroupId());

$serializer = $this->createMock(SerializerInterface::class);
$serializer->method('encode')->with($envelope)->willReturn($encoded);

$sender = new AmazonSqsSender($connection, $serializer);
$sender->send($envelope);
}

public function testSendWithAmazonSqsFairQueueStampWontWorkAlongsideFifoStamp()
{
$envelope = (new Envelope(new DummyMessage('Oy')))
->with($fifoStamp = new AmazonSqsFifoStamp('testGroup', 'testDeduplicationId'))
->with(new AmazonSqsFairQueueStamp('tenant-123'));

$encoded = ['body' => '...', 'headers' => ['type' => DummyMessage::class]];

$connection = $this->createMock(Connection::class);
$connection->expects($this->once())->method('send')
->with($encoded['body'], $encoded['headers'], 0, $fifoStamp->getMessageGroupId(), $fifoStamp->getMessageDeduplicationId());

$serializer = $this->createMock(SerializerInterface::class);
$serializer->method('encode')->with($envelope)->willReturn($encoded);

$sender = new AmazonSqsSender($connection, $serializer);
$sender->send($envelope);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Messenger\Bridge\AmazonSqs\Transport;

use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;

final class AmazonSqsFairQueueStamp implements NonSendableStampInterface
{
public function __construct(
private string $messageGroupId,
) {
}

public function getMessageGroupId(): string
{
return $this->messageGroupId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public function send(Envelope $envelope): Envelope
$messageDeduplicationId = $amazonSqsFifoStamp->getMessageDeduplicationId();
}

$amazonSqsFairQueueStamp = $envelope->last(AmazonSqsFairQueueStamp::class);
if (null === $amazonSqsFifoStamp && null !== $amazonSqsFairQueueStamp) {
$messageGroupId = $amazonSqsFairQueueStamp->getMessageGroupId();
}

/** @var AmazonSqsXrayTraceHeaderStamp|null $amazonSqsXrayTraceHeaderStamp */
$amazonSqsXrayTraceHeaderStamp = $envelope->last(AmazonSqsXrayTraceHeaderStamp::class);
$xrayTraceId = $amazonSqsXrayTraceHeaderStamp?->getTraceId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ public function send(string $body, array $headers, int $delay = 0, ?string $mess
$parameters['MessageGroupId'] = $messageGroupId ?? __METHOD__;
$parameters['MessageDeduplicationId'] = $messageDeduplicationId ?? sha1(json_encode(['body' => $body, 'headers' => $headers]));
unset($parameters['DelaySeconds']);
} elseif (null !== $messageGroupId) {
$parameters['MessageGroupId'] = $messageGroupId;
}

$this->client->sendMessage($parameters);
Expand Down
Loading