Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEXT-31249 - async low priority queue documentation #1153

Merged
merged 5 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions guides/hosting/infrastructure/message-queue.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ nav:

## Overview

::: warning
Parts of this guide refer to the `low_priority` queue, which is only available in version 6.5.7.0 and above. Configuring the messenger to consume this queue will fail if it does not exist.
:::

Shopware uses the Symfony Messenger component and Enqueue to handle asynchronous messages. This allows tasks to be processed in the background. Thus, tasks can be processed independently of timeouts or system crashes. By default, tasks in Shopware are stored in the database and processed via the browser as long as you are logged into the Administration. This is a simple and fast method for the development process, but not recommended for production systems. With multiple users logged into the Administration, this can lead to a high CPU load and interfere with the smooth execution of PHP FPM.

## Message queue on production systems
Expand Down Expand Up @@ -41,6 +45,14 @@ You can configure the command just to run a certain amount of time and to stop i
bin/console messenger:consume async --time-limit=60 --memory-limit=128M
```

You can also configure the command to consume messages from multiple transports to prioritize them to your needs, as it is recommended by the [Symfony documentation](https://symfony.com/doc/current/messenger.html#prioritized-transports):

```bash

```bash
bin/console messenger:consume async low_priority
```

For more information about the command and its configuration, use the -h option:

```bash
Expand Down Expand Up @@ -77,7 +89,7 @@ User=www-data # Change this to webserver's user name
Restart=always
# Change the path to your shop path
WorkingDirectory=/var/www/html
ExecStart=php /var/www/html/bin/console messenger:consume --time-limit=60 --memory-limit=512M async
ExecStart=php /var/www/html/bin/console messenger:consume --time-limit=60 --memory-limit=512M async low_priority

[Install]
WantedBy=shopware_consumer.target
Expand Down Expand Up @@ -108,6 +120,10 @@ Please refer to the [Symfony documentation](https://symfony.com/doc/current/mess

### Admin worker

::: warning
The `transports` option can only be configured with the `low_priority` transport if you are on version 6.5.7.0 or above. You can't add the `low_priority` transport in lower versions as the admin worker will fail when it tries to consume a non-existent transport.
:::

The admin worker, if used, can be configured in the general `shopware.yml` configuration. If you want to use the admin worker, you have to specify each transport that was previously configured. The poll interval is the time in seconds that the admin worker polls messages from the queue. After the poll interval is over, the request terminates, and the Administration initiates a new request.

```yaml
Expand All @@ -116,7 +132,7 @@ shopware:
admin_worker:
enable_admin_worker: true
poll_interval: 30
transports: ["async"]
transports: ["async", "low_priority"]
```

## Sending mails over the message queue
Expand All @@ -143,6 +159,7 @@ You can find all available transport options in the Symfony Messenger documentat
Following environment variables are in use out of the box:

* `MESSENGER_TRANSPORT_DSN` - The DSN to the transport to use (e.g. `doctrine://default`).
* `MESSENGER_TRANSPORT_LOW_PRIORITY_DSN` - The DSN to the transport to use for low priority messages (e.g. `doctrine://default?queue_name=low_priority`).
* `MESSENGER_TRANSPORT_FAILURE_DSN` - The DSN to the transport to use for failed messages (e.g. `doctrine://default?queue_name=failed`).

## Worker count for efficient message processing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ nav:

## Overview

::: warning
Parts of this guide refer to the `low_priority` queue, which is only available in version 6.5.7.0 and above. Configuring the messenger to consume this queue will fail if it does not exist.
:::

In this guide you'll learn how to create a message handler.

A [handler](https://symfony.com/doc/current/messenger.html#creating-a-message-handler) gets called once the message is dispatched by the `handle_messages` middleware. Handlers do the actual processing of the message.
Expand Down Expand Up @@ -49,7 +53,14 @@ There is a console command to start a worker that will receive incoming messages
bin/console messenger:consume async
```

Where `async` is the transport you want to consume message from. There is also an API-Route that lets you consume messages for a given transport. Just post to the route `/api/_action/message-queue/consume` and define the transport from which you want to consume:
You can also append more transports to the command, so the worker will consume messages from multiple transports which will result in prioritization as mentioned in [Prioritized Transports](https://symfony.com/doc/current/messenger.html#prioritized-transports):

```bash
//
bin/console messenger:consume async low_priority
```

Where `async` and `low_priority` are the transports you want to consume messages from. There is also an API route that lets you consume messages for a given transport. send a `POST` request to the route `/api/_action/message-queue/consume` and define the transport which you want to consume:

```js
// on
Expand Down Expand Up @@ -77,12 +88,12 @@ The recommended way to consume messages is through the cli command. You can conf

```bash
//
bin/console messenger:consume async --time-limit=60
bin/console messenger:consume async low_priority --time-limit=60
```

```bash
//
bin/console messenger:consume async --memory-limit=128M
bin/console messenger:consume async low_priority --memory-limit=128M
```

For more information about the command and its configuration use the `-h` option:
Expand Down Expand Up @@ -164,6 +175,10 @@ You can route messages by their classname and use the asterisk as a fallback for

### Admin worker

::: warning
The `transports` option can only be configured with the `low_priority` transport if you are on version 6.5.7.0 or above. You must not add the `low_priority` transport in lower versions, as the admin worker will fail when it tries to consume a non-existent transport.
:::

The admin-worker can be configured or disabled in the general `shopware.yml` configuration. If you want to use the admin worker you have to specify each transport, that previously was configured. The poll interval is the time in seconds that the admin-worker polls messages from the queue. After the poll-interval is over the request terminates and the Administration initiates a new request.

```yaml
Expand All @@ -172,7 +187,7 @@ shopware:
admin_worker:
enable_admin_worker: true
poll_interval: 30
transports: ["async"]
transports: ["async", "low_priority"]
```

## Next steps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ nav:

## Overview

::: warning
Parts of this guide refer to the `low_priority` queue and the corresponding `LowPriorityMessageInterface`, which is only available in version 6.5.7.0 and above. Configuring the messenger to consume this queue will fail if it does not exist.
:::

In this guide you'll learn how to create a message and add it to the queue.

Shopware integrates with the [Symfony Messenger](https://symfony.com/doc/current/components/messenger.html) component and [Enqueue](https://enqueue.forma-pro.com/). This gives you the possibility to send and handle asynchronous messages.
Expand All @@ -23,7 +27,7 @@ As most guides, this guide is also built upon the [Plugin base guide](../../plug

## Create a message

First, we have to create a new message class in the directory `<plugin root>/MessageQueue/Message`. In this example, we create a `SmsNotification` that contains a string with content. By default, all messages are handled synchronously, to change the behavior to asynchronously we have to implement the `AsyncMessageInterface` interface.
First, we have to create a new message class in the directory `<plugin root>/MessageQueue/Message`. In this example, we create a `SmsNotification` that contains a string with content. By default, all messages are handled synchronously. To change the behavior to asynchronously, we have to implement the `AsyncMessageInterface` interface. For messages which should also be handled asynchronously but with a lower priority, implement the `LowPriorityMessageInterface` interface.

Here's an example:

Expand Down Expand Up @@ -94,6 +98,45 @@ public function sendMessage(string $message): void
}
```

## Lower the priority for specific async messages

You might consider using the new `low_priority` queue if you are dispatching messages that do not need to be handled immediately. To configure specific messages to be transported via the `low_priority` queue, you need to either adjust the routing or implement the `LowPriorityMessageInterface` as already mentioned:

```yaml
# config/packages/framework.yaml
framework:
messenger:
routing:
'Your\Custom\Message': low_priority
```

## Override transport for specific messages

If you explicitly configure a message to be transported via the `async` (default) queue, even though it implements the `LowPriorityMessageInterface`, which would usually be transported via the `low_priority` queue, the transport is overridden for this specific message.

Example:
```php
// <plugin root>/src/MessageQueue/Message/LowPriorityMessage.php
<?php declare(strict_types=1);

namespace Your\Custom;

use Shopware\Core\Framework\MessageQueue\LowPriorityMessageInterface;

class LowPriorityMessage implements LowPriorityMessageInterface
{
}
```

```yaml
# config/packages/framework.yaml
framework:
messenger:
routing:
'Shopware\Core\Framework\MessageQueue\LowPriorityMessageInterface': low_priority
'Your\Custom\LowPriorityMessage': async
```

## Encrypted messages

As the sent messages may travel through some 3rd party services you may want to encrypt messages containing sensible information. To send encrypted messages simply use the `encrypted.messenger.bus.shopware` rather than the `messenger.bus.shopware` message bus. The encrypted bus will handle encryption and decryption for you.
Expand Down