Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Messenger] No need for retry to require SentStamp #32053

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

Merged
merged 1 commit into from
Jun 24, 2019

Conversation

Tobion
Copy link
Contributor

@Tobion Tobion commented Jun 14, 2019

Q A
Branch? 4.3
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets
License MIT
Doc PR

Fixes 2) in #32049
@weaverryan the SentStamp in the worker seems totally irrelevant. You always want to send messages back to the transport where they came from for retry. The only relevance I can potentially see is for the SyncTransport. Messages received async from worker might be routed to the SyncTransport. Using the SentStamp would redeliver the messages into the SyncTransport instead of the async. But that doesn't seem to have any use-case. I'm running the worker which handles the messages immediately. So basically there is no difference if they go to the Sync or Async transport from within the worker.

@Tobion Tobion requested a review from sroze as a code owner June 14, 2019 20:27
@Tobion Tobion force-pushed the no-need-for-retry-to-require-sentstamp branch 2 times, most recently from 48f5d21 to 675eb85 Compare June 14, 2019 20:46
@Tobion Tobion requested a review from weaverryan June 14, 2019 20:48
@Tobion Tobion force-pushed the no-need-for-retry-to-require-sentstamp branch from 675eb85 to 0034dee Compare June 14, 2019 21:41
@nicolas-grekas nicolas-grekas added this to the 4.3 milestone Jun 15, 2019
@@ -150,7 +148,7 @@ private function handleMessage(Envelope $envelope, ReceiverInterface $receiver,

// add the delay and retry stamp info + remove ReceivedStamp
$retryEnvelope = $envelope->with(new DelayStamp($delay))
->with(new RedeliveryStamp($retryCount, $this->getSenderClassOrAlias($envelope)))
->with(new RedeliveryStamp($retryCount, $transportName))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The edge case I believe I was coding for (and maybe we decide it's not legitimate) is if you send on transport/sender A but receive on transport/receiver B. It's an odd case, but in that situation, we would (I think?) want to re-send to sender A, not receiver B. Thoughts?

Copy link
Contributor Author

@Tobion Tobion Jun 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory you could receive a message from transport B but route it to transport A for sending.
But in the end, senders and receivers are bound together by TransportInterface which requires implementing both. So if you do the above, you still have to implement sending part in transport B. So you could just use the same sender in transport B that you use in transport A if you need to cover retry going to transport A.
So to me that is an edge case that people can solve in custom transports. Nothing we should take care of by default. And in case we want to account for this later, the better and more explicit solution to me is to add a config option on the transport to configure the retry_transport (similar to the failure_transport).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is if you send on transport/sender A but receive on transport/receiver B

I also don't see how SentStamp should work for this case anyway. If a message comes from transport B, it cannot have the SentStamp pointing to transport A. If it was sent to transport B, it also has the SentStamp pointing to B (at least the last SentStamp) added by SendMessageMiddleware.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't see how SentStamp should work for this case anyway

It would work like this:

A) Send a message on TransportA. The message now has a SentStamp for TransportA.
B) Receive message on TransportB. The message will, of course, still only have the SentStamp for TransportA.

It's an edge case where, for example, you're using AMQP and send to TransportA, which has some routing & binding keys that ultimately put it in some queue "foo". Then, for whatever reason, you setup TransportB to receive from queue "foo". In this case, you will directly "receive" a message from TransportB that only has a SentStamp for TransportA.

But in the end, senders and receivers are bound together by TransportInterface which requires implementing both

I think that's not true... at least on a low, component level. I believe that, when routing, you can set the class to route to any service id that has the SenderInterface, even if it's not defined as a transport (and doesn't define a TransportInterface). I think the same is true for receiving messages: I think you can pass any service id to messenger:consume.

Sorry to complicate things - this is what "possible" situation that was floating around when this was originally coded.

The tl;dr is this: the SentStamp is the concrete way to mark exactly which sender sent a message so that we can definitely use the same sender during redelivery. But yes, we could add a retry_transport option, which could act as an override for SentStamp/be used when that stamp is not available. Or, if the stamp is not available, we could "try" to redeliver to the "receiver" (and throw an exception if it doesn't implement SenderInterface).

Copy link
Contributor Author

@Tobion Tobion Jun 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to not have the SentStamp logic. We agreed it tries to solve an edge case. To me that is something SF Messenger should not code against. It potentially breaks as much as it solves. For example, if I sent a Message to transport A, rename the transport to B and deploy again. Suddenly the retry of all existing messages in the queue breaks because it still tries to resend to A but A does not exist anymore. And with delayed messages of hours or days, this can easily happen.

How do we proceed now?

  1. accept the PR to remove SentStamp logic from retry in 4.3
  2. try to implement both the SentStamp logic and fallback to receiver
  3. as 2) but remove the SentStamp logic only in 4.4 to avoid potential bc break in 4.3

I'm in favor of 1).
2) would make the messenger behavior context dependent which I don't like at all.

@Tobion Tobion merged commit 0034dee into symfony:4.3 Jun 24, 2019
Tobion added a commit that referenced this pull request Jun 24, 2019
This PR was merged into the 4.3 branch.

Discussion
----------

[Messenger] No need for retry to require SentStamp

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets |
| License       | MIT
| Doc PR        |

Fixes 2) in #32049
@weaverryan the SentStamp in the worker seems totally irrelevant. You always want to send messages back to the transport where they came from for retry. The only relevance I can potentially see is for the SyncTransport. Messages received async from worker might be routed to the SyncTransport. Using the SentStamp would redeliver the messages into the SyncTransport instead of the async. But that doesn't seem to have any use-case. I'm running the worker which handles the messages immediately. So basically there is no difference if they go to the Sync or Async transport from within the worker.

Commits
-------

0034dee [Messenger] make retry logic work without SentStamp
@Tobion Tobion deleted the no-need-for-retry-to-require-sentstamp branch June 24, 2019 22:32
@fabpot fabpot mentioned this pull request Jun 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants