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] Added documentation about DispatchAfterCurrentBusMiddleware#10015
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
javiereguiluz commentedJul 4, 2018
@Nyholm thanks for this contribution! Lately in the Symfony Docs we're trying to not add new articles when they are too short. So, do you think we could move this article to a section inside an existing article? If there is no article where we can put this ... or if such article is already super long, we could consider creating this new article. Thanks! |
Nyholm commentedJul 4, 2018
messenger/message-recorder.rst Outdated
| .. code-block:: yaml | ||
| # config/packages/workflow.yaml |
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.
- workflow.yaml+ messenger.yaml
messenger/message-recorder.rst Outdated
| Record Events Produced by a Handler | ||
| =================================== | ||
| In a example application there is a command (a CQRS message) named ``CreateUser``. |
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.
"In an example"
messenger/message-recorder.rst Outdated
| =================================== | ||
| In a example application there is a command (a CQRS message) named ``CreateUser``. | ||
| That command is handled by the ``CreateUserHandler``. The command handler creates |
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.
- by the ``CreateUserHandler``. The command handler creates+ by the ``CreateUserHandler`` which creates
?
messenger/message-recorder.rst Outdated
| In a example application there is a command (a CQRS message) named ``CreateUser``. | ||
| That command is handled by the ``CreateUserHandler``. The command handler creates | ||
| a ``User`` object, stores that object to a database and dispatches an ``UserCreatedEvent``. |
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.
"a UserCreatedEvent"
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 you sure?
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.
Almost :) I'm not native. But you wrote "a User" just before. Seehttps://english.stackexchange.com/questions/105116/is-it-a-user-or-an-user
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 would say that "a User" was a typo.
I read your source. I did not know that. Thank you. I've updated the PR.
messenger/message-recorder.rst Outdated
| There are many subscribers to the ``UserCreatedEvent``, one subscriber may send | ||
| a welcome email to the new user. Since we are using the ``DoctrineTransactionMiddleware`` | ||
| we wrap all database queries in one database transaction and rollback that transaction | ||
| if an exception is thrown. That would mean that if an exception is thrown when sending |
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.
- That would mean+ That means
messenger/message-recorder.rst Outdated
| - messenger.middleware.validation | ||
| - messenger.middleware.handles_recorded_messages: ['@messenger.bus.event'] | ||
| # Doctrine transaction must be after handles_recorded_messages middleware | ||
| - app.doctrine_transaction_middleware: ['default'] |
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.
What about using an FQCN forapp.doctrine_transaction_middleware? or may we explicit the definition somewhere. If possible I'd rather use the class 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.
I have an idea that this will be on the same page as#10013 where we useapp.doctrine_transaction_middleware.
Uh oh!
There was an error while loading.Please reload this page.
messenger/message-recorder.rst Outdated
| $this->em = $em; | ||
| } | ||
| public function __invoke(CreateUser $command) |
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're missing use statements for domain classes, what about:
useApp\Entity\User;useApp\Messenger\Command\CreateUser;useApp\Messenger\Event\UserCreatedEvent;
?
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.
Thank you
messenger/message-recorder.rst Outdated
| Record Events Produced by a Handler | ||
| =================================== | ||
| In an example application there is a command (a CQRS message) named ``CreateUser``. |
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.
- In an example application there is a command (a CQRS message) named ``CreateUser``.+ Let's take the example of an application that has a command (a CQRS message) named ``CreateUser``.
?
messenger/message-recorder.rst Outdated
| In an example application there is a command (a CQRS message) named ``CreateUser``. | ||
| That command is handled by the ``CreateUserHandler`` which creates | ||
| a ``User`` object, stores that object to a database and dispatches a ``UserCreatedEvent``. |
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.
UserCreated event?
messenger/message-recorder.rst Outdated
| That event is also a normal message but is handled by an *event* bus. | ||
| There are many subscribers to the ``UserCreatedEvent``, one subscriber may send | ||
| a welcome email to the new user. Since we are using the ``DoctrineTransactionMiddleware`` |
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'd suggest to split the two and explicit the "problem":
- Since we are using the ``DoctrineTransactionMiddleware`` [...]+ We are using the ``DoctrineTransactionMiddleware`` to wrap all database queries in one database transaction.++ **Problem:** if an exception is thrown when sending the welcome email, then the user will not be created because the ``DoctrineTransactionMiddleware`` will rollback the Doctrine transaction, in which the user has been created.
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.
Nice. Thank you
messenger/message-recorder.rst Outdated
| if an exception is thrown. That means that if an exception is thrown when sending | ||
| the welcome email, then the user will not be created. | ||
| The solution to this issue is to not dispatch the ``UserCreatedEvent`` in 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.
Same, I'd highlight the solution:
**Solution:**messenger/message-recorder.rst Outdated
| .. index:: | ||
| single: Messenger; Record messages | ||
| Record Events Produced by a Handler |
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.
Might be better to find a name that describes the problem than the technical solution. Something like "Event recorder: Tolerating failures while in Doctrine transactions"?
messenger/message-recorder.rst Outdated
| $user = new User($command->getUuid(), $command->getName(), $command->getEmail()); | ||
| $this->em->persist($user); | ||
| $this->eventRecorder->record(new UserCreatedEvent($command->getUuid()); |
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.
You need to explain what this does, right? Because it does more than "recording" the event. Actually, this call doespostpone the event dispatching isn't it?
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 EventRecorder is just a storage. There is a middleware that reads from that store later. But yes, I'll write something
Nyholm commentedAug 26, 2018
Thank you for the review. I've updated the PR accordingly |
arnolanglade 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.
It would be good to add a rich modelUser with a named constructorsignUp that will recored aSignedUpUser event.
messenger/message-recorder.rst Outdated
| Events Recorder: Handle Events After CommandHandler Is Done | ||
| =========================================================== | ||
| Let's take the example of an application that has a command (a CQRS message) named |
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 nota CQRS message but message. You suer messages too when you application use the CQS pattern for example.
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.
Indeed, CQRS doesn't necessitate any form of messages. Could "an imperative domain message" be an option? Or maybe a more thorough definition could be useful.
messenger/message-recorder.rst Outdated
| =========================================================== | ||
| Let's take the example of an application that has a command (a CQRS message) named | ||
| ``CreateUser``. That command is handled by the ``CreateUserHandler`` which creates |
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 could be better to useSignUpUser as command name, it is less focus on CRUD action.
Uh oh!
There was an error while loading.Please reload this page.
messenger/message-recorder.rst Outdated
| $this->em->persist($user); | ||
| // "Record" this event to be processed later by "handles_recorded_messages". | ||
| $this->eventRecorder->record(new UserCreatedEvent($command->getUuid()); |
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 event should be produced by the user model.
messenger/message-recorder.rst Outdated
| Events Recorder: Handle Events After CommandHandler Is Done | ||
| =========================================================== | ||
| Let's take the example of an application that has a command (a CQRS message) named |
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.
Indeed, CQRS doesn't necessitate any form of messages. Could "an imperative domain message" be an option? Or maybe a more thorough definition could be useful.
messenger/message-recorder.rst Outdated
| ``CreateUserHandler`` but to just "record" the events. The recorded events will | ||
| be dispatched after ``DoctrineTransactionMiddleware`` has committed the transaction. | ||
| To enable this, you simply just add the ``messenger.middleware.handles_recorded_messages`` |
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 should remove "simply just", because it's just filler, and not everyone would consider this simple.
gubler commentedFeb 24, 2019
The current PRsymfony/symfony#28849 replaces the RecordsMessages middleware and recorder with a My rewrite is here:https://github.com/gubler/messenger-transaction-test/blob/master/docs/transactional-messages.rst I tried to take into account previous comments on this request. Feel free to take whatever is useful from my rewrite. |
Nyholm commentedFeb 24, 2019
gubler commentedFeb 24, 2019
Done - though its the first time I've done this, so I apologize if I messed anything up :/ |
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Nyholm commentedMar 17, 2019
We should not forget this:symfony/symfony#28849 (comment) |
Nyholm commentedMar 17, 2019
I did some updates to the docs to keep up-to-date with the symfony PR. I also added some screenshots to this PR description. I hope they will address any questions about the functionality and to help you (everyone) to help me explain this in the docs. |
…t bus is finished (Nyholm)This PR was merged into the 4.3-dev branch.Discussion----------[Messenger] Support for handling messages after current bus is finished| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets || License | MIT| Doc PR |symfony/symfony-docs#10015This is a replacement for#27844. We achieve the same goals without introducing the new concept of "recorder".```phpclass CreateUserHandler{ private $em; private $eventBus; public function __construct(MessageBus $eventBus, EntityManagerInterface $em) { $this->eventBus = $eventBus; $this->em = $em; } public function __invoke(CreateUser $command) { $user = new User($command->getUuid(), $command->getName(), $command->getEmail()); $this->em->persist($user); $message = new UserCreatedEvent($command->getUuid(); $this->eventBus->dispatch((new Envelope($message))->with(new DispatchAfterCurrentBus())); }}```Note that this `DispatchAfterCurrentBusMiddleware` is added automatically as the first middleware.2019-03-13: I updated the PR description.Commits-------903355f Support for handling messages after current bus is finished
sroze commentedMar 20, 2019
Thank you@Nyholm! |
Nyholm commentedApr 8, 2019
@sroze could you add your review? |
The current PR is for HandleMessageInNewTransaction middleware instead of the original RecordsMessages middleware. This documentation covers the new middleware.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Co-Authored-By: Nyholm <tobias.nyholm@gmail.com>
Co-Authored-By: Nyholm <tobias.nyholm@gmail.com>
Co-Authored-By: Nyholm <tobias.nyholm@gmail.com>
Co-Authored-By: Nyholm <tobias.nyholm@gmail.com>
| .. index:: | ||
| single: Messenger; Record messages; Transaction messages | ||
| Transactional Messages: Handle Events After CommandHandler is Done |
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.
@javiereguiluz s/After/after/ ?
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.
Except these few details, it looks good to me 👍
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Nyholm commentedApr 28, 2019
Thank you for the review. I've updated accordingly |
weaverryan commentedMay 24, 2019
Nyholm commentedMay 24, 2019
Thank you for merging. |
…dleware entry (weaverryan)This PR was merged into the 4.3 branch.Discussion----------[Messenger] Tweaks for DispatchAfterCurrentBusMiddleware entryJust some proofreading changes forsymfony#10015!Commits-------599d10b minor reorg of new DispatchAfterCurrentBusMiddleware
Uh oh!
There was an error while loading.Please reload this page.
Documentation to PR:symfony/symfony#27844