mirror of
https://github.com/symfony/messenger.git
synced 2026-03-23 23:52:14 +01:00
Merge branch '7.4' into 8.0
* 7.4: (25 commits) [RateLimiter] Fix retryAfter when consuming exactly all remaining tokens in FixedWindow and TokenBucket [RateLimiter] Fix retryAfter value on last token consume (SlidingWindow) [RateLimiter] Fix reservations outside the second fixed window [Filesystem] makePathRelative with existing files, remove ending / [Config][Routing] Fix exclude option being ignored for non-glob and PSR-4 resources [Serializer][Validator] Fix propertyPath in ConstraintViolationListNormalizer with MetadataAwareNameConverter [Messenger][Amqp] Don't use retry routing key when sending to failure transport [Messenger] Fix re-sending failed messages to a different failure transport [DependencyInjection] Fix #[AsTaggedItem] discovery through multi-level decoration chains [Config] Fix ArrayShapeGenerator required keys with deep merging [Validator] Add a guard when `Parser::IGNORE_UNKNOWN_VARIABLES` is not defined [Validator] Correctly handle null `allowedVariables` in `ExpressionSyntaxValidator` [DependencyInjection] Fix PriorityTaggedServiceTrait not discovering #[AsTaggedItem] on decorated services [Mailer] Clarify the purpose of SentMessage's "message id" concept [ObjectMapper] fix nested mapping with class-level transform [TwigBridge] Fix Bootstrap 4 form error layout [Form] Fix merging POST params and files when collection entries have mismatched indices [Validator] Fix type error for non-array items when Unique::fields is set [HttpKernel] Fix default locale ignored when Accept-Language has no enabled-locale match [FrameworkBundle] Make `ConfigDebugCommand` use its container to resolve env vars ...
This commit is contained in:
@@ -30,6 +30,7 @@ class SendFailedMessageToFailureTransportListener implements EventSubscriberInte
|
||||
public function __construct(
|
||||
private ContainerInterface $failureSenders,
|
||||
private ?LoggerInterface $logger = null,
|
||||
private array $failureTransportsByName = [],
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -48,7 +49,10 @@ class SendFailedMessageToFailureTransportListener implements EventSubscriberInte
|
||||
$envelope = $event->getEnvelope();
|
||||
|
||||
// avoid re-sending to the failed sender
|
||||
if (null !== $envelope->last(SentToFailureTransportStamp::class)) {
|
||||
if (!$this->failureTransportsByName && $envelope->last(SentToFailureTransportStamp::class)) {
|
||||
return;
|
||||
}
|
||||
if (($this->failureTransportsByName[$event->getReceiverName()] ?? null) === $event->getReceiverName()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class SendFailedMessageToFailureTransportListenerTest extends TestCase
|
||||
}))->willReturnArgument(0);
|
||||
|
||||
$serviceLocator = new ServiceLocator([
|
||||
$receiverName => fn () => $sender,
|
||||
$receiverName => static fn () => $sender,
|
||||
]);
|
||||
$listener = new SendFailedMessageToFailureTransportListener($serviceLocator);
|
||||
|
||||
@@ -60,14 +60,62 @@ class SendFailedMessageToFailureTransportListenerTest extends TestCase
|
||||
$listener->onMessageFailed($event);
|
||||
}
|
||||
|
||||
public function testDoNotRedeliverToFailedWithServiceLocator()
|
||||
public function testDoNotRedeliverToSelfReferentialFailureTransport()
|
||||
{
|
||||
$receiverName = 'my_receiver';
|
||||
|
||||
$sender = $this->createMock(SenderInterface::class);
|
||||
$sender->expects($this->never())->method('send');
|
||||
|
||||
$listener = new SendFailedMessageToFailureTransportListener(new ServiceLocator([]));
|
||||
$serviceLocator = new ServiceLocator([
|
||||
$receiverName => static fn () => $sender,
|
||||
]);
|
||||
// The failure transport for 'my_receiver' is itself: skip to prevent an infinite loop
|
||||
$listener = new SendFailedMessageToFailureTransportListener($serviceLocator, null, [$receiverName => $receiverName]);
|
||||
$envelope = new Envelope(new \stdClass());
|
||||
$event = new WorkerMessageFailedEvent($envelope, $receiverName, new \Exception());
|
||||
|
||||
$listener->onMessageFailed($event);
|
||||
}
|
||||
|
||||
public function testItForwardsToChainedFailureTransportWhenDifferentFromReceiver()
|
||||
{
|
||||
$receiverName = 'failed';
|
||||
$chainedFailureTransportName = 'super_failed';
|
||||
|
||||
$sender = $this->createMock(SenderInterface::class);
|
||||
$sender->expects($this->once())->method('send')->with($this->callback(function ($envelope) use ($receiverName) {
|
||||
$this->assertInstanceOf(Envelope::class, $envelope);
|
||||
$sentToFailureTransportStamp = $envelope->last(SentToFailureTransportStamp::class);
|
||||
$this->assertNotNull($sentToFailureTransportStamp);
|
||||
$this->assertSame($receiverName, $sentToFailureTransportStamp->getOriginalReceiverName());
|
||||
|
||||
return true;
|
||||
}))->willReturnArgument(0);
|
||||
|
||||
$serviceLocator = new ServiceLocator([
|
||||
$receiverName => static fn () => $sender,
|
||||
]);
|
||||
// The failure transport for 'failed' is 'super_failed' (different): it should forward
|
||||
$listener = new SendFailedMessageToFailureTransportListener($serviceLocator, null, [$receiverName => $chainedFailureTransportName]);
|
||||
$envelope = new Envelope(new \stdClass());
|
||||
$event = new WorkerMessageFailedEvent($envelope, $receiverName, new \Exception());
|
||||
|
||||
$listener->onMessageFailed($event);
|
||||
}
|
||||
|
||||
public function testDoNotRedeliverToFailedWithStampFallback()
|
||||
{
|
||||
$receiverName = 'my_receiver';
|
||||
|
||||
$sender = $this->createMock(SenderInterface::class);
|
||||
$sender->expects($this->never())->method('send');
|
||||
|
||||
// No $failureTransportsByName: falls back to SentToFailureTransportStamp check
|
||||
$serviceLocator = new ServiceLocator([
|
||||
$receiverName => static fn () => $sender,
|
||||
]);
|
||||
$listener = new SendFailedMessageToFailureTransportListener($serviceLocator);
|
||||
$envelope = new Envelope(new \stdClass(), [
|
||||
new SentToFailureTransportStamp($receiverName),
|
||||
]);
|
||||
@@ -104,7 +152,7 @@ class SendFailedMessageToFailureTransportListenerTest extends TestCase
|
||||
}))->willReturnArgument(0);
|
||||
|
||||
$serviceLocator = new ServiceLocator([
|
||||
$receiverName => fn () => $sender,
|
||||
$receiverName => static fn () => $sender,
|
||||
]);
|
||||
|
||||
$listener = new SendFailedMessageToFailureTransportListener($serviceLocator);
|
||||
|
||||
Reference in New Issue
Block a user