Skip to content

Commit 599d10b

Browse files
committed
minor reorg of new DispatchAfterCurrentBusMiddleware
1 parent 5e1033a commit 599d10b

File tree

1 file changed

+21
-83
lines changed

1 file changed

+21
-83
lines changed

messenger/message-recorder.rst

Lines changed: 21 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.. index::
22
single: Messenger; Record messages; Transaction messages
33

4-
Transactional Messages: Handle Events After CommandHandler is Done
4+
Transactional Messages: Handle New Messages After Handling is Done
55
==================================================================
66

77
A message handler can ``dispatch`` new messages during execution, to either the same or
@@ -11,18 +11,18 @@ such as:
1111

1212
- If using the ``DoctrineTransactionMiddleware`` and a dispatched message throws an exception,
1313
then any database transactions in the original handler will be rolled back.
14-
- If the message is dispatched to a different bus, then dispatched message will be
15-
handled even if the current handler throws an exception.
14+
- If the message is dispatched to a different bus, then the dispatched message will
15+
be handled even if some code later in the current handler throws an exception.
1616

1717
An Example ``RegisterUser`` Process
1818
-----------------------------------
1919

2020
Let's take the example of an application with both a *command* and an *event* bus. The application
2121
dispatches a command named ``RegisterUser`` to the command bus. The command is handled by the
2222
``RegisterUserHandler`` which creates a ``User`` object, stores that object to a database and
23-
dispatches a ``UserRegistered`` event to the event bus.
23+
dispatches a ``UserRegistered`` message to the event bus.
2424

25-
There are many subscribers to the ``UserRegistered`` event, one subscriber may send
25+
There are many handlers to the ``UserRegistered`` message, one handler may send
2626
a welcome email to the new user. We are using the ``DoctrineTransactionMiddleware``
2727
to wrap all database queries in one database transaction.
2828

@@ -33,88 +33,14 @@ Doctrine transaction, in which the user has been created.
3333
**Problem 2:** If an exception is thrown when saving the user to the database, the welcome
3434
email is still sent because it is handled asynchronously.
3535

36-
``DispatchAfterCurrentBusMiddleware`` Middleware
37-
------------------------------------------------
36+
DispatchAfterCurrentBusMiddleware Middleware
37+
--------------------------------------------
3838

39-
For many applications, the desired behavior is to have any messages dispatched by the handler
40-
to `only` be handled after the handler finishes. This can be by using the
39+
For many applications, the desired behavior is to *only* handle messages that are
40+
dispatched by a handler once that handler has fully finished. This can be by using the
4141
``DispatchAfterCurrentBusMiddleware`` middleware and adding a ``DispatchAfterCurrentBusStamp``
4242
stamp to `the message Envelope </components/messenger#adding-metadata-to-messages-envelopes>`_.
4343

44-
Referencing the above example, this means that the ``UserRegistered`` event would not be handled
45-
until *after* the ``RegisterUserHandler`` had completed and the new ``User`` was persisted to the
46-
database. If the ``RegisterUserHandler`` encounters an exception, the ``UserRegistered`` event will
47-
never be handled and if an exception is thrown while sending the welcome email, the Doctrine
48-
transaction will not be rolled back.
49-
50-
The ``dispatch_after_current_bus`` middleware is enabled by default. It is configured as the
51-
first middleware on all busses. When doing a highly custom or special configuration, then make
52-
sure ``dispatch_after_current_bus`` is registered before ``doctrine_transaction``
53-
in the middleware chain.
54-
55-
**Note:** The ``dispatch_after_current_bus`` middleware must be loaded for *all* of the
56-
buses. For the example, the middleware must be loaded for both the command and event bus.
57-
58-
.. configuration-block::
59-
60-
.. code-block:: yaml
61-
62-
# config/packages/messenger.yaml
63-
framework:
64-
messenger:
65-
default_bus: messenger.bus.command
66-
67-
buses:
68-
messenger.bus.command:
69-
middleware:
70-
- validation
71-
messenger.bus.event:
72-
default_middleware: allow_no_handlers
73-
middleware:
74-
- validation
75-
76-
.. code-block:: xml
77-
78-
<!-- config/packages/messenger.xml -->
79-
<?xml version="1.0" encoding="UTF-8" ?>
80-
<container xmlns="http://symfony.com/schema/dic/services"
81-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
82-
xmlns:framework="http://symfony.com/schema/dic/symfony"
83-
xsi:schemaLocation="http://symfony.com/schema/dic/services
84-
https://symfony.com/schema/dic/services/services-1.0.xsd">
85-
86-
<framework:config>
87-
<framework:messenger default_bus="messenger.bus.command">
88-
<framework:bus name="messenger.bus.command">
89-
<framework:middleware id="validation">
90-
<framework:middleware id="doctrine_transaction">
91-
</framework:bus>
92-
<framework:bus name="messenger.bus.command" default_middleware="allow_no_handlers">
93-
<framework:middleware id="validation">
94-
<framework:middleware id="doctrine_transaction">
95-
</framework:bus>
96-
</framework:messenger>
97-
</framework:config>
98-
</container>
99-
100-
.. code-block:: php
101-
102-
// config/packages/messenger.php
103-
$container->loadFromExtension('framework', [
104-
'messenger' => [
105-
'default_bus' => 'messenger.bus.command',
106-
'buses' => [
107-
'messenger.bus.command' => [
108-
'middleware' => ['validation', 'doctrine_transaction'],
109-
],
110-
'messenger.bus.event' => [
111-
'default_middleware' => 'allow_no_handlers',
112-
'middleware' => ['validation', 'doctrine_transaction'],
113-
],
114-
],
115-
],
116-
]);
117-
11844
.. code-block:: php
11945
12046
namespace App\Messenger\CommandHandler;
@@ -185,8 +111,20 @@ buses. For the example, the middleware must be loaded for both the command and e
185111
}
186112
}
187113
114+
This means that the ``UserRegistered`` message would not be handled
115+
until *after* the ``RegisterUserHandler`` had completed and the new ``User`` was persisted to the
116+
database. If the ``RegisterUserHandler`` encounters an exception, the ``UserRegistered`` event will
117+
never be handled. And if an exception is thrown while sending the welcome email, the Doctrine
118+
transaction will not be rolled back.
119+
188120
.. note::
189121

190122
If ``WhenUserRegisteredThenSendWelcomeEmail`` throws an exception, that exception
191123
will be wrapped into a ``DelayedMessageHandlingException``. Using ``DelayedMessageHandlingException::getExceptions``
192124
will give you all exceptions that are thrown while handing a message with the ``DispatchAfterCurrentBusStamp``.
125+
126+
The ``dispatch_after_current_bus`` middleware is enabled by default. If you're
127+
configuring your middleware manually, be sure to register
128+
``dispatch_after_current_bus`` before ``doctrine_transaction`` in the middleware
129+
chain. Also, the ``dispatch_after_current_bus`` middleware must be loaded for *all* of
130+
the buses being used.

0 commit comments

Comments
 (0)