-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Messenger] Refactoring failure to FailedMessage & allowing for requeue #31397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Messenger] Refactoring failure to FailedMessage & allowing for requeue #31397
Conversation
9bd0543
to
86975f5
Compare
86975f5
to
4c83e1c
Compare
4c83e1c
to
6b19228
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much of this PR is just a revert of part of #30970. I've highlighted those to help review.
@@ -1768,29 +1788,11 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder | |||
|
|||
$container->getDefinition('messenger.senders_locator') | |||
->replaceArgument(0, $messageToSendersMapping) | |||
->replaceArgument(1, ServiceLocatorTagPass::register($container, $senderReferences)) | |||
->replaceArgument(2, $messagesToSendAndHandle) | |||
->replaceArgument(1, $messagesToSendAndHandle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the logic from $senders = []
is a revert of #30970
if (!isset($senderAliases[$failureTransport])) { | ||
$senderAliases[$failureTransport] = $failureTransport; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section was mostly just moved from below. The $messagesToSendersMapping
is the new part: it adds routing
for the FailedMessage
class to whatever the failure transport is.
|
||
<tag name="console.command" command="messenger:failed:remove" /> | ||
</service> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved into a new file so we can conditionally import that file (instead importing, then removing if the failure transport is disabled).
@@ -9,8 +9,7 @@ | |||
|
|||
<!-- Asynchronous --> | |||
<service id="messenger.senders_locator" class="Symfony\Component\Messenger\Transport\Sender\SendersLocator"> | |||
<argument type="collection" /> <!-- Per message senders map --> | |||
<argument /> <!-- senders locator --> | |||
<argument type="collection" /> <!-- Per message sender iterators --> | |||
<argument type="collection" /> <!-- Messages to send and handle --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert of #30970
$this->assertEquals(new Reference('audit'), $sendersLocator->getArgument(0)['audit']->getValues()[0]); | ||
'amqp' => new Reference('messenger.transport.amqp'), | ||
'audit' => new Reference('audit'), | ||
], $sendersMapping[DummyMessage::class]->getValues()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert of #30970
} | ||
|
||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert of #30970
}); | ||
|
||
return new SendersLocator($sendersMap, $container, $sendAndHandle); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whole class is a revert of #30970
$this->assertTrue($stampToRedeliverToSender1->shouldRedeliverToSender('App\Sender1', null)); | ||
$this->assertFalse($stampToRedeliverToSender1->shouldRedeliverToSender('App\Sender2', null)); | ||
} | ||
|
||
public function testGetters() | ||
{ | ||
$stamp = new RedeliveryStamp(10, 'sender_alias'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert of #30970
}); | ||
|
||
return $container; | ||
$this->assertSame(['dummy' => $sender], iterator_to_array($locator->getSenders(new Envelope(new DummyMessage('a'))))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert of #30970
} | ||
|
||
throw new UnknownSenderException(sprintf('Unknown sender alias "%s".', $alias)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert of #30970
8e62086
to
d4f483f
Compare
use Symfony\Component\Messenger\Transport\Sender\SendersLocator; | ||
use Symfony\Component\Messenger\Worker; | ||
|
||
class FailureIntegrationTest extends TestCase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is a bit crazy. There are various layers that interact, and this proves the work together:
- The ability to send a message to multiple transports but some handlers are only called on some transports
- The failure transport and the requeuing of messages
- The failure transport and retrying messages (instead of requeuing) and making sure the correct handlers are still called.
src/Symfony/Component/Messenger/Failure/SendFailedMessageToFailureTransportListener.php
Show resolved
Hide resolved
src/Symfony/Component/Messenger/Failure/SendFailedMessageToFailureTransportListener.php
Outdated
Show resolved
Hide resolved
6020703
to
1b0b49d
Compare
I like the new implementation. But now that FailedMessage are routed using the standard config, does it not mean that the FailedMessage will also be routed to transports configured by the user using the wildcard, e.g. |
src/Symfony/Component/Messenger/Failure/FailedMessageHandler.php
Outdated
Show resolved
Hide resolved
1b0b49d
to
c776abd
Compare
c776abd
to
3ab3a85
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed on Slack, I think this approach as multiple downsides:
- It doesn't work with
*
as @Tobion spotted well - It forces the failure transport to only use the PHP
serialize
serializer (because Symfony Serializer couldn't know how to deserialize theFailedMessage
message; especially its innerEnvelope
) - It forces the entirety of the "system" to only have one "failure transport"
Also, all of this change is trigged by the point 2) of the pull-request description, which, IMHO, could be simply achieved by dispatching the message again (without the ReceivedStamp
). I agree that we need to look at 3) which might be a bug though.
@@ -1745,19 +1743,41 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder | |||
|
|||
$messageToSendersMapping = []; | |||
$messagesToSendAndHandle = []; | |||
if ($config['failure_transport']) { | |||
$failureTransport = $config['failure_transport']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line could be in the if
:)
After talking with Sam & Nicolas (and @Tobion's feedback), I'm closing this PR. Most of this code was a refactoring, which didn't contain enough objective improvements over the previous implementation. We can propose requeue for 4.4, as it's a new feature. And for:
I'll attempt to fix this independently in another PR. |
There are a few things going on:
Purely because I think it's a better implementation, I've created a new
FailedMessage
class and the failed messages go inside of this. This message is then routed to the failure transport.This adds the ability to "requeue" messages instead of retrying them immediately, based on feedback from Twitter.
This should fix an undiscovered bug: if you "retry" and use [Messenger] Allows to register handlers on a specific transport #30958, previously, retrying would not execute the correct handlers because it would appear the message was being received from the "failure" transport, not the original transport, which has configuration to execute specific handlers.
Cheers!