Skip to content

Commit afdddbf

Browse files
Nyholmweaverryan
authored andcommitted
Added documentation about message recorder
1 parent cde5dde commit afdddbf

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

messenger/message-recorder.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
.. index::
2+
single: Messenger; Record messages
3+
4+
Record Events Produced by a Handler
5+
===================================
6+
7+
In a example application there is a command (a CQRS message) named ``CreateUser``.
8+
That command is handled by the ``CreateUserHandler``. The command handler creates
9+
a ``User`` object, stores that object to a database and dispatches an ``UserCreatedEvent``.
10+
That event is also a normal message but is handled by an *event* bus.
11+
12+
There are many subscribers to the ``UserCreatedEvent``, one subscriber may send
13+
a welcome email to the new user. Since we are using the ``DoctrineTransactionMiddleware``
14+
we wrap all database queries in one database transaction and rollback that transaction
15+
if an exception is thrown. That would mean that if an exception is thrown when sending
16+
the welcome email, then the user will not be created.
17+
18+
The solution to this issue is to not dispatch the ``UserCreatedEvent`` in the
19+
``CreateUserHandler`` but to just "record" the events. The recorded events will
20+
be dispatched after ``DoctrineTransactionMiddleware`` has committed the transaction.
21+
22+
To enable this, you simply just add the ``messenger.middleware.handles_recorded_messages``
23+
middleware. Make sure it is registered before ``DoctrineTransactionMiddleware``
24+
in the middleware chain.
25+
26+
.. configuration-block::
27+
28+
.. code-block:: yaml
29+
30+
# config/packages/workflow.yaml
31+
framework:
32+
messenger:
33+
default_bus: messenger.bus.command
34+
buses:
35+
messenger.bus.command:
36+
middleware:
37+
- messenger.middleware.validation
38+
- messenger.middleware.handles_recorded_messages: ['@messenger.bus.event']
39+
# Doctrine transaction must be after handles_recorded_messages middleware
40+
- app.doctrine_transaction_middleware: ['default']
41+
messenger.bus.event:
42+
middleware:
43+
- messenger.middleware.allow_no_handler
44+
- messenger.middleware.validation
45+
46+
.. code-block:: php
47+
48+
use Doctrine\ORM\EntityManagerInterface;
49+
use Symfony\Component\Messenger\MessageRecorderInterface;
50+
51+
class CreateUserHandler
52+
{
53+
private $em;
54+
private $eventRecorder;
55+
56+
public function __construct(MessageRecorderInterface $eventRecorder, EntityManagerInterface $em)
57+
{
58+
$this->eventRecorder = $eventRecorder;
59+
$this->em = $em;
60+
}
61+
62+
public function __invoke(CreateUser $command)
63+
{
64+
$user = new User($command->getUuid(), $command->getName(), $command->getEmail());
65+
$this->em->persist($user);
66+
67+
$this->eventRecorder->record(new UserCreatedEvent($command->getUuid());
68+
}
69+
}

0 commit comments

Comments
 (0)