diff --git a/components/messenger.rst b/components/messenger.rst index 7e1af990db1..c8339be3b02 100644 --- a/components/messenger.rst +++ b/components/messenger.rst @@ -146,6 +146,9 @@ Here are some important envelope stamps that are shipped with the Symfony Messen #. :class:`Symfony\\Component\\Messenger\\Stamp\\DelayStamp`, to delay handling of an asynchronous message. +#. :class:`Symfony\\Component\\Messenger\\Stamp\\PriorityStamp`, + to prioritize messages of the same type within a queue. Read more + at :doc:`/messenger/message_priority`. #. :class:`Symfony\\Component\\Messenger\\Stamp\\DispatchAfterCurrentBusStamp`, to make the message be handled after the current bus has executed. Read more at :doc:`/messenger/dispatch_after_current_bus`. diff --git a/messenger/message_priority.rst b/messenger/message_priority.rst new file mode 100644 index 00000000000..6d473de031a --- /dev/null +++ b/messenger/message_priority.rst @@ -0,0 +1,136 @@ +Message Priority +================ + +By default messenger uses the first in, first out principle: messages will be +received in the same order they were sent (except the delayed ones). + +Basic priority can be achieved by using :doc:`prioritized transports `, +but only for different message types. + +With AMQP and Beanstalkd transports, you can have a priority queue for messages +of the same type:: + + use Symfony\Component\Messenger\Envelope; + use Symfony\Component\Messenger\Stamp\PriorityStamp; + + $bus->dispatch( + (new Envelope($message))->with(new PriorityStamp(255)) + ); + +.. tip:: + + Priorities between ``0`` (lowest) and ``255`` (highest) are supported. + +Priority can be used together with delay:: + + use Symfony\Component\Messenger\Envelope; + use Symfony\Component\Messenger\Stamp\DelayStamp; + use Symfony\Component\Messenger\Stamp\PriorityStamp; + + $bus->dispatch( + (new Envelope($message))->with( + new PriorityStamp(255), + new DelayStamp(5000) + ) + ); + +When the time comes, if other messages in queue have lower priority, this one +will be delivered first. + +Using with Beanstalkd transport +------------------------------- + +Beanstalkd does not require any additional configuration. You can start using priority +stamp right away. + +.. note:: + + Internally Beanstalkd uses a different priority system, where priority + can take values between ``2^32 - 1`` and ``0``, with zero being the highest priority. + Messenger handles the transformation internally. + +Using with AMQP transport +------------------------- + +With AMQP transport, you need to enable priority for the queue in configuration: + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/messenger.yaml + framework: + messenger: + transports: + async: + dsn: "%env(MESSENGER_TRANSPORT_DSN)%" + options: + queues: + messenger: + arguments: + x-max-priority: 255 + + .. code-block:: xml + + + + + + + + + + + + 255 + + + + + + + + + + .. code-block:: php + + // config/packages/messenger.php + use Symfony\Config\FrameworkConfig; + + return static function (FrameworkConfig $framework) { + $messenger = $framework->messenger(); + + $messenger->transport('async') + ->dsn('%env(MESSENGER_TRANSPORT_DSN)%') + ->options([ + 'queues' => [ + 'messenger' => [ + 'arguments' => [ + 'x-max-priority' => 255, + ], + ] + ] + ]); + }; + +.. caution:: + + It's not safe to set ``x-max-priority`` for an existing queue. + RabbitMQ can not change existing queue's configuration. Messenger will + fail to auto-setup and priorities won't work. + +.. note:: + + `RabbitMQ manual recommends`_ using up to 10 different priority levels. + For example, you may use 255 for high, 127 for medium and 0 for low priority. + Having more levels may have an impact on performance. + +.. _`RabbitMQ manual recommends`: https://www.rabbitmq.com/priority.html