Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork5.3k
[Messenger] Add the Envelope in the documentation#9757
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
weaverryan left a comment
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.
I made some minor tweaks (please check to make sure I didn't change anything important - was just meant to be language tweaks. And, 2 questions
components/messenger.rst Outdated
| { | ||
| public function handle($message, callable $next) | ||
| { | ||
| // $message here is an `Envelope` object |
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.
is it always an Envelope? Or maybe itcould be an Envolope?
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.
It's always anEnvelope if you implements the interface.
ogizanagiMay 22, 2018 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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.
Note: that's true considering our bus implementation which will always inject the message wrapped in an Envelope. But we currently also useEnvelope::wrap in envelope aware middleware and most tests are callinghandle on envelope aware middleware with a message directly, not an envelope.
We could removeEnvelope::wrap and fix tests of these middleware, but IMHO it's still another hintsymfony/symfony#27322 is needed for clarity & better design.
components/messenger.rst Outdated
| return $next( | ||
| $message->with(new AnotherEnvelopeItem(/* ... */)) | ||
| ); |
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.
Is this the main use-case for an envelop-aware middleware? Or would we more commonly be reading some configuration from the envelope?
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.
Both are good use cases tbh
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.
I think reading would be way more common and should be showcased instead. I would put a note about being extra cautious about altering the envelope or its message as it'll be completely transparent. Even if there are legit use-cases.
About altering/replacing the message, the tactician docs says:
You don’t have to pass the same command to $next that came in! If you’re working with a legacy system and want to convert or modify the incoming commands, you’re free to do so. Just think carefully!
Also showing an example where we read the envelope items would make the purpose of those items more understandable.
ogizanagi left a comment
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.
I as about to (try to) work on this. Thanks for taking care of it ❤️
Should we update the schema in order to represent that receivers get a message wrapped into an envelope and senders send an Envelope too?
Adding anEnvelope entry below it would be helpful too (with a link to this new section).
components/messenger.rst Outdated
| ])) | ||
| ); | ||
| Instead of dealing directly with the message in the handlers or middleware, you |
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.
handlers will always get the message (and I think it should stay as is as the end of the pipe), never the Envelope, so I think mentioning handlers here is misleading.
components/messenger.rst Outdated
| return $next( | ||
| $message->with(new AnotherEnvelopeItem(/* ... */)) | ||
| ); |
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.
I think reading would be way more common and should be showcased instead. I would put a note about being extra cautious about altering the envelope or its message as it'll be completely transparent. Even if there are legit use-cases.
About altering/replacing the message, the tactician docs says:
You don’t have to pass the same command to $next that came in! If you’re working with a legacy system and want to convert or modify the incoming commands, you’re free to do so. Just think carefully!
Also showing an example where we read the envelope items would make the purpose of those items more understandable.
components/messenger.rst Outdated
| It willwrap the received messages into``ReceivedMessage``objects and the | ||
| ``SendMessageMiddleware`` middleware will know it should not route these | ||
| messagesagain to a transport. | ||
| It willadd a``ReceivedMessage``configuration to the message envelopes and the |
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.
- configuration+ marker item
?
components/messenger.rst Outdated
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| To allow us to receive and send messages on the same bus and prevent an infinite | ||
| loop, the message bus is equipped with the ``WrapIntoReceivedMessage`` middleware. |
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.
Actually, theWrapIntoReceivedMessage is neither a middleware, neither it is used in Symfony core. That's theWorker that call thereceive method with a$handleradding theReceivedMessage marker to the envelope.
Hence I wondered multiple times if it was really intended? Should we remove theWrapIntoReceivedMessage decorator? Should we decorate in the core any created receiver? Should the worker only dispatch the received envelope to the bus, or keep addingReceivedMessage?
| 'groups' => ['my_serialization_groups'], | ||
| ])) | ||
| ); | ||
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 could mention others built-in configurations available (justValidationConfiguration for now) here or in another section.
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.
Just did 👍
sroze left a comment
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.
Updated :)
| 'groups' => ['my_serialization_groups'], | ||
| ])) | ||
| ); | ||
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.
Just did 👍
sroze commentedJun 3, 2018
@weaverryan can you have another look please? |
components/messenger.rst Outdated
| { | ||
| // $message here is an `Envelope` object, because this middleware | ||
| // implements the EnvelopeAwareInterface interface. Otherwise, | ||
| // it would be the "original" message. |
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.
I think we should remove the last sentence. I think it's obvious that, if you do NOT implement ``EnvelopeAwareInterface`, that you receive the normal message. So, this sentence made me wonder if you were actually saying something different.
components/messenger.rst Outdated
| // implements the EnvelopeAwareInterface interface. Otherwise, | ||
| // it would be the "original" message. | ||
| if (null !== $message->get(ReceivedMessage::class)) { |
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.
Is thisget() method something that lives onEnvelope? Isn't there always just one message inside an Envelope? If so, why do we pass an argument here? Or, could you also pass something like$message->get(SerializerConfiguration::class) to get those types of things out?
Also, suppose some similar code: if$message->get(MyMessage::class) is null, does it mean that this message is NOT originally aMyMessage isntance, right? I mean, it's equivalent to!$message instanceof MyMessage in a middleware withoutEnvelopAwareInterface?
Some inline comments with some of these answers might be all we need :)
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.
Also, is it a real use-case to look need to know whether or not a message was just received? If you're using an async transport and you want to do something for a specific message type, is it important that you make sure this processing is done only when your message has been "received"? If so, why? And if so, how could I both perform my action only when the message is "received" AND only check the class of the original message (e.g. I need to do something when myMyMessage class is "received"? Or is that totally not the correct pattern.
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.
if $message->get(MyMessage::class) is null, does it mean that this message is NOT originally a MyMessage isntance, right?
There is mis interpretation here. TheReceivedMessage class is not an example here, it's an actual envelope item within the component has is a marker that represents that the message has just been received. It's needed to have the router middleware ignoring them (otherwise we would have a receive -> send) loop.
Or, could you also pass something like $message->get(SerializerConfiguration::class) to get those types of things out?
That's notalso, that's the only thing you can do :)
how could I both perform my action only when the message is "received" AND only check the class of the original message
if (nul !==$message->get(ReceivedMessage::class) &&$message->getMessage()instanceof YourOwnMessageClass) {// Your logic...}
Might be clearer if werename$message to$envelope?
components/messenger.rst Outdated
| } | ||
| } | ||
| Envelope |
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.
The title of this section and the introduction is not very clear to me. Here is a reword proposal:
Before:
Envelope--------The notion of an envelope is a concept that helps add context around themessages. An envelope is a message and a set of data. From a user's perspective, thisallows you to set some configuration around the message. For example, to set the serializationgroups used when the message goes through the transport layer, wrap your messagein an ``Envelope`` and add some ``SerializerConfiguration``::
After:
Adding Metadata to Messages (Envelopes)---------------------------------------If you need to add metadata or some configuration to a message, wrap it with the:class:`Symfony\\Component\\Messenger\\Envelope` class. For example, to set theserialization groups used when the message goes through the transport layer, usethe ``SerializerConfiguration`` envelope::
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 better 👍
javiereguiluz commentedJun 27, 2018
Ping to@sroze. Will you have some time to fix the final issues of this PR? Thanks! |
components/messenger.rst Outdated
| } | ||
| } | ||
| Envelope |
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 better 👍
components/messenger.rst Outdated
| class MyOwnMiddleware implements MiddlewareInterface, EnvelopeAwareInterface | ||
| { | ||
| public function handle($message, callable $next) |
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.
Actually, maybe we can rename$message to$envelope in this example? PHP allows us to do so (i.e. variable names not to match with the name in the interface). It might be clearer.
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.
Yes. Please rename this.
components/messenger.rst Outdated
| // implements the EnvelopeAwareInterface interface. Otherwise, | ||
| // it would be the "original" message. | ||
| if (null !== $message->get(ReceivedMessage::class)) { |
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.
if $message->get(MyMessage::class) is null, does it mean that this message is NOT originally a MyMessage isntance, right?
There is mis interpretation here. TheReceivedMessage class is not an example here, it's an actual envelope item within the component has is a marker that represents that the message has just been received. It's needed to have the router middleware ignoring them (otherwise we would have a receive -> send) loop.
Or, could you also pass something like $message->get(SerializerConfiguration::class) to get those types of things out?
That's notalso, that's the only thing you can do :)
how could I both perform my action only when the message is "received" AND only check the class of the original message
if (nul !==$message->get(ReceivedMessage::class) &&$message->getMessage()instanceof YourOwnMessageClass) {// Your logic...}
Might be clearer if werename$message to$envelope?
sroze commentedJun 30, 2018
@javiereguiluz pong :) |
Nyholm left a comment
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.
Good. Just that minor change renaming the variable
weaverryan commentedJul 12, 2018
Thank you@sroze! Sorry for the delay! I did rename the variable to $envelope as suggested. Cheers! |
…e, weaverryan)This PR was merged into the 4.1 branch.Discussion----------[Messenger] Add the Envelope in the documentationBecause we've merged this beautiful PR :)Commits-------a87d727 Renaming variable16c7385 Merge branch '4.1' into messenger-envelopedd8b368 Reword the header regarding the envelope357fe25 Add message envelope in the documentation
* 4.1: Simplified the "Release Process" page [Workflow] Fix typo documentation Fix mismatched list items typos in sample code [symfony#9988] fix minor typos [symfony#10099] update XML and PHP config examples [symfony#9969] fix a minor typo [symfony#10022] fix a minor typo preUpdate Event Listener On Uploaded Imagery [symfony#9757] fix rst syntax [symfony#10124] fix XML attribute name [symfony#10062] fix the code block [PHPUnitBridge] Explain how to show stack traces Fix docs on trusted hosts opcode optimizations
Because we've merged this beautiful PR :)