-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Messenger] Ability to distinguish retry and delay actions #36864
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
Conversation
102bf8e
to
f6e8c45
Compare
Neither would this be allowed in master since it would break apps migrating to 5.2. Can we find another idea? |
798e402
to
d3124bf
Compare
@nicolas-grekas Thank you for the feedback. I changed it: now Should I change target branch in this case? |
Yes please if this should be considered as a bugfix (I didn't check that part). |
d3124bf
to
aa81532
Compare
@nicolas-grekas changed target to 4.4 |
@@ -45,7 +46,12 @@ public function getAttributes(): array | |||
return $this->attributes; | |||
} | |||
|
|||
public static function createFromAmqpEnvelope(\AMQPEnvelope $amqpEnvelope, self $previousStamp = null): self | |||
public function isEnvelopeRedelivered(): bool |
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 is really confusing. AMQP also has the concept of redelivery. But this is not the same as the redelivery in the messenger component. Since this is the stamp to encode the amqp flags, this is really unexpected. So this needs a different name or not be exposed at all.
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 has been renamed
@theravel i was able to solve this and few other problems without changing Messenger connection class, but it's little bit tricky. Here is an example https://github.com/s-code/amqp-extra-bundle. Take a look on ExtraAmqpFactory, ExtraAmqpSender, ExtraAmqpQueue, ExtraAmqpExchange. |
On a high level, this makes sense to me: If a message is in queue A, and I read it from queue A and it fails, then it should go back onto queue A only. Messenger handles retries by actually ack'ing the original message and redelivering it. But ultimately, the desired behavior (I think) would be what I described above and what this PR does. Though, apparently this and #38486 solve the same problem (is it the exact same problem?) but in different ways. @s-code could you comment on what your PR does versus this one? Thanks :) |
@weaverryan you are right. This two pull requests solve the same problem. The difference is in next things:
|
aa81532
to
5d084a2
Compare
(please add a changelog entry in the bridge) |
@nicolas-grekas Changelog entry added |
src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpStamp.php
Outdated
Show resolved
Hide resolved
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.
Im happy with this. Just one question
@@ -45,7 +46,7 @@ public function getAttributes(): array | |||
return $this->attributes; | |||
} | |||
|
|||
public static function createFromAmqpEnvelope(\AMQPEnvelope $amqpEnvelope, self $previousStamp = null): self | |||
public static function createFromAmqpEnvelope(\AMQPEnvelope $amqpEnvelope, self $previousStamp = null, string $retryRoutingKey = null): self |
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.
We are using $amqpReceivedStamp->getQueueName()
to populate the $retryRoutingKey
, is that really correct?
A routing key is not the same as the queue name.
(It is probably correct, but I just need you to clarify.)
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 is correct. We want to distinguish:
- delay scenario, where message should be sent to original exchange to original routing key (so that all consumers can get it)
- retry scenario, where message should be sent to default (direct) exchange to routing key which matches queue name (in this case it will be received in one queue only)
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.
Are we sure the routing key always matches the queue name?
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.
For direct exchange in AMQP 0-9-1 yes:
The default exchange is a direct exchange with no name (empty string) pre-declared by the broker. It has one special property that makes it very useful for simple applications: every queue that is created is automatically bound to it with a routing key which is the same as the queue name.
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.
@Nyholm can you review please?
I believe it is always the case with direct exchange.
The default exchange is a direct exchange with no name (empty string) pre-declared by the broker. It has one special property that makes it very useful for simple applications: every queue that is created is automatically bound to it with a routing key which is the same as the queue name.
… On 21 Apr 2021, at 15:40, Tobias Nyholm ***@***.***> wrote:
@Nyholm commented on this pull request.
In src/Symfony/Component/Messenger/Bridge/Amqp/Transport/AmqpStamp.php:
> @@ -45,7 +46,7 @@ public function getAttributes(): array
return $this->attributes;
}
- public static function createFromAmqpEnvelope(\AMQPEnvelope $amqpEnvelope, self $previousStamp = null): self
+ public static function createFromAmqpEnvelope(\AMQPEnvelope $amqpEnvelope, self $previousStamp = null, string $retryRoutingKey = null): self
Are we sure the routing key always matches the queue name?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Thank you @theravel and @MichaelKubovic for confirming. |
35a6ada
to
417aaab
Compare
Thank your for this feature. Please update the docs too =) |
Added ability to distinguish retry and delay actions so that different "x-dead-letter-exchange" exchange name will be used in different scenarios.
This is a bug which existed since v4.4. The following scenario is possible:
A
andB
, both are bound to the same routing key via "topic" exchange (two different applications for example).A
handles it correctly and acknowledges the message.B
throws and exception and message goes to retry (for example to queuedelay_delays_key_5
).delay_delays_key_5
, it is delivered again to bothA
andB
(again consumed by consumerA
).Expected: behavior of consumer
B
should not cause message duplication to queueA
.It is required to make a change of name of temporary delay queue (otherwise "delay" and "retry" queues have incompatible declaration arguments). I left
queue_name_pattern
as is to keep settings of connection backward compatible, but changed internals of queue name construction.