From 06045118841d520699754d24fcb0f19c104b393c Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Mon, 12 Nov 2018 13:13:58 +0100 Subject: [PATCH 1/2] [Messenger] Backport some changes from 4.2 branch --- components/messenger.rst | 10 ++--- messenger.rst | 92 ++++++++++++++++++++-------------------- 2 files changed, 52 insertions(+), 50 deletions(-) diff --git a/components/messenger.rst b/components/messenger.rst index ce2ab655153..ecc5d854424 100644 --- a/components/messenger.rst +++ b/components/messenger.rst @@ -38,8 +38,8 @@ Concepts something can be a message broker or a third party API for example. **Receiver**: - Responsible for deserializing and forwarding messages to handler(s). This - can be a message queue puller or an API endpoint for example. + Responsible for retrieving, deserializing and forwarding messages to handler(s). + This can be a message queue puller or an API endpoint for example. **Handler**: Responsible for handling messages using the business logic applicable to the messages. @@ -55,7 +55,7 @@ are configured for you: #. ``LoggingMiddleware`` (logs the processing of your messages) #. ``SendMessageMiddleware`` (enables asynchronous processing) -#. ``HandleMessageMiddleware`` (calls the registered handle) +#. ``HandleMessageMiddleware`` (calls the registered handler) Example:: @@ -206,7 +206,7 @@ First, create your sender:: Your own Receiver ~~~~~~~~~~~~~~~~~ -A receiver is responsible for receiving messages from a source and dispatching +A receiver is responsible for getting messages from a source and dispatching them to the application. Imagine you already processed some "orders" in your application using a @@ -226,7 +226,7 @@ First, create your receiver:: use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Messenger\Envelope; - class NewOrdersFromCsvFile implements ReceiverInterface + class NewOrdersFromCsvFileReceiver implements ReceiverInterface { private $serializer; private $filePath; diff --git a/messenger.rst b/messenger.rst index 002acd02e5e..24e311c5465 100644 --- a/messenger.rst +++ b/messenger.rst @@ -84,7 +84,9 @@ message handler. It's a class with an ``__invoke`` method:: Message handlers must be registered as services and :doc:`tagged ` with the ``messenger.message_handler`` tag. If you're using the -:ref:`default services.yaml configuration `, +:ref:`default services.yaml configuration ` and implement +:class:`Symfony\\Component\\Messenger\\Handler\\MessageHandlerInterface` +or :class:`Symfony\\Component\\Messenger\\Handler\\MessageSubscriberInterface`, this is already done for you, thanks to :ref:`autoconfiguration `. If you're not using service autoconfiguration, then you need to add this config: @@ -543,11 +545,16 @@ for each bus looks like this: #. ``call_message_handler`` middleware. Will call the message handler(s) for the given message. -Adding your own Middleware -~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. note:: -As described in the component documentation, you can add your own middleware -within the buses to add some extra capabilities like this: + These middleware names are actually shortcuts working by convention. + The real service ids are prefixed with the ``messenger.middleware.`` namespace. + +Disabling default Middleware +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you don't want the default collection of middleware to be present on your bus, +you can disable them like this: .. configuration-block:: @@ -558,9 +565,7 @@ within the buses to add some extra capabilities like this: messenger: buses: messenger.bus.default: - middleware: - - 'App\Middleware\MyMiddleware' - - 'App\Middleware\AnotherMiddleware' + default_middleware: false .. code-block:: xml @@ -576,10 +581,7 @@ within the buses to add some extra capabilities like this: - - - - + @@ -591,23 +593,17 @@ within the buses to add some extra capabilities like this: 'messenger' => array( 'buses' => array( 'messenger.bus.default' => array( - 'middleware' => array( - 'App\Middleware\MyMiddleware', - 'App\Middleware\AnotherMiddleware', - ), + 'default_middleware' => false, ), ), ), )); -Note that if the service is abstract, a different instance of service will be -created per bus. - -Disabling default Middleware -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Adding your own Middleware +~~~~~~~~~~~~~~~~~~~~~~~~~~ -If you don't want the default collection of middleware to be present on your bus, -you can disable them like this: +As described in the component documentation, you can add your own middleware +within the buses to add some extra capabilities like this: .. configuration-block:: @@ -618,7 +614,9 @@ you can disable them like this: messenger: buses: messenger.bus.default: - default_middleware: false + middleware: + - 'App\Middleware\MyMiddleware' + - 'App\Middleware\AnotherMiddleware' .. code-block:: xml @@ -634,7 +632,10 @@ you can disable them like this: - + + + + @@ -646,12 +647,18 @@ you can disable them like this: 'messenger' => array( 'buses' => array( 'messenger.bus.default' => array( - 'default_middleware' => false, + 'middleware' => array( + 'App\Middleware\MyMiddleware', + 'App\Middleware\AnotherMiddleware', + ), ), ), ), )); +Note that if the service is abstract, a different instance of service will be +created per bus. + Using Middleware Factories ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -674,13 +681,13 @@ factories. Defining such requires a two-step configuration based on Symfony's # Step 2: an abstract definition that will call the factory with default # arguments or the ones provided in the middleware config - messenger.middleware.doctrine_transaction_middleware: + messenger.middleware.doctrine_transaction: class: Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddleware factory: 'doctrine.orm.messenger.middleware_factory.transaction:createMiddleware' abstract: true # the default arguments to use when none provided from config. Example: # middleware: - # - doctrine_transaction_middleware: ~ + # - doctrine_transaction: ~ arguments: ['default'] .. code-block:: xml @@ -703,7 +710,7 @@ factories. Defining such requires a two-step configuration based on Symfony's - @@ -729,7 +736,7 @@ factories. Defining such requires a two-step configuration based on Symfony's // Step 2: an abstract definition that will call the factory with default // arguments or the ones provided in the middleware config - $container->register('messenger.middleware.doctrine_transaction_middleware', DoctrineTransactionMiddleware::class) + $container->register('messenger.middleware.doctrine_transaction', DoctrineTransactionMiddleware::class) ->setFactory(array( new Reference('doctrine.orm.messenger.middleware_factory.transaction'), 'createMiddleware' @@ -742,7 +749,7 @@ which is the argument expected by the ``Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddlewareFactory::createMiddleware`` method. Then you can reference and configure the -``messenger.middleware.doctrine_transaction_middleware`` service as a middleware: +``messenger.middleware.doctrine_transaction`` service as a middleware: .. configuration-block:: @@ -755,9 +762,9 @@ Then you can reference and configure the command_bus: middleware: # Using defaults - - doctrine_transaction_middleware + - doctrine_transaction # Using another entity manager - - doctrine_transaction_middleware: ['custom'] + - doctrine_transaction: ['custom'] .. code-block:: xml @@ -775,9 +782,9 @@ Then you can reference and configure the - + - + custom @@ -794,20 +801,15 @@ Then you can reference and configure the 'command_bus' => array( 'middleware' => array( // Using defaults - 'doctrine_transaction_middleware', + 'doctrine_transaction', // Using another entity manager - array('id' => 'doctrine_transaction_middleware', 'arguments' => array('custom')), + array('id' => 'doctrine_transaction', 'arguments' => array('custom')), ), ), ), ), )); -.. note:: - - The ``doctrine_transaction_middleware`` shortcut is a convention. The real - service id is prefixed with the ``messenger.middleware.`` namespace. - .. note:: Middleware factories only allow scalar and array arguments in config (no @@ -816,9 +818,9 @@ Then you can reference and configure the .. tip:: - The ``doctrine_transaction_middleware`` is a built-in middleware wired - automatically when the DoctrineBundle and the Messenger component are - installed and enabled. + The ``messenger.middleware.doctrine_transaction`` middleware is a built-in + middleware wired automatically when the DoctrineBundle and the Messenger + component are installed and enabled. Your own Transport ------------------ From 9fbabde3684d2cfde28e330c4440a4bb3a31c759 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Mon, 12 Nov 2018 13:58:14 +0100 Subject: [PATCH 2/2] [Messenger] Add more notes about base concepts, envelope items & class refs --- components/messenger.rst | 41 ++++++++++++++++++++++++++++++++++------ messenger.rst | 4 ++-- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/components/messenger.rst b/components/messenger.rst index ecc5d854424..2700e3eec55 100644 --- a/components/messenger.rst +++ b/components/messenger.rst @@ -43,6 +43,28 @@ Concepts **Handler**: Responsible for handling messages using the business logic applicable to the messages. + Handlers are called by the ``HandleMessageMiddleware`` middleware. + +**Middleware**: + Middleware can access the message and its wrapper (the envelope) while it is + dispatched through the bus. + Literally *"the software in the middle"*, those are not about core concerns + (business logic) of an application. Instead, they are cross cutting concerns + applicable throughout the application and affecting the entire message bus. + For instance: logging, validating a message, starting a transaction, ... + They are also responsible for calling the next middleware in the chain, + which means they can tweak the envelope, by adding items to it or even + replacing it, as well as interrupt the middleware chain. + +**Envelope** + Messenger specific concept, it gives full flexibility inside the message bus, + by wrapping the messages into it, allowing to add useful information inside + through *envelope items*. + +**Envelope Items** + Piece of information you need to attach to your message: serializer context + to use for transport, markers identifying a received message or any sort of + metadata your middleware or transport layer may use. Bus --- @@ -53,9 +75,9 @@ middleware stack. The component comes with a set of middleware that you can use. When using the message bus with Symfony's FrameworkBundle, the following middleware are configured for you: -#. ``LoggingMiddleware`` (logs the processing of your messages) -#. ``SendMessageMiddleware`` (enables asynchronous processing) -#. ``HandleMessageMiddleware`` (calls the registered handler) +#. :class:`Symfony\\Component\\Messenger\\Middleware\\LoggingMiddleware` (logs the processing of your messages) +#. :class:`Symfony\\Component\\Messenger\\Asynchronous\\Middleware\\SendMessageMiddleware` (enables asynchronous processing) +#. :class:`Symfony\\Component\\Messenger\\Middleware\\HandleMessageMiddleware` (calls the registered handler(s)) Example:: @@ -74,7 +96,7 @@ Example:: .. note:: - Every middleware needs to implement the ``MiddlewareInterface``. + Every middleware needs to implement the :class:`Symfony\\Component\\Messenger\\Middleware\\MiddlewareInterface`. Handlers -------- @@ -112,7 +134,7 @@ the ``SerializerConfiguration`` envelope:: ])) ); -At the moment, the Symfony Messenger has the following built-in envelopes: +At the moment, the Symfony Messenger has the following built-in envelope items: #. :class:`Symfony\\Component\\Messenger\\Transport\\Serialization\\SerializerConfiguration`, to configure the serialization groups used by the transport. @@ -151,6 +173,12 @@ The above example will forward the message to the next middleware with an additi envelope item *if* the message has just been received (i.e. has the `ReceivedMessage` item). You can create your own items by implementing :class:`Symfony\\Component\\Messenger\\EnvelopeAwareInterface`. +.. note:: + + Any envelope item must be php serializable if going through transport using + the :class:`Symfony\\Component\\Messenger\\Transport\\Serialization\\Serializer` + base serializer. + Transports ---------- @@ -160,7 +188,8 @@ transport will be responsible for communicating with your message broker or 3rd Your own Sender ~~~~~~~~~~~~~~~ -Using the ``SenderInterface``, you can create your own message sender. +Using the :class:`Symfony\\Component\\Messenger\\Transport\\SenderInterface`, +you can create your own message sender. Imagine that you already have an ``ImportantAction`` message going through the message bus and being handled by a handler. Now, you also want to send this message as an email. diff --git a/messenger.rst b/messenger.rst index 24e311c5465..14f5f4d906e 100644 --- a/messenger.rst +++ b/messenger.rst @@ -656,8 +656,8 @@ within the buses to add some extra capabilities like this: ), )); -Note that if the service is abstract, a different instance of service will be -created per bus. +Note that if the service is abstract, a different instance of the service will +be created per bus. Using Middleware Factories ~~~~~~~~~~~~~~~~~~~~~~~~~~