diff --git a/code_samples/background_tasks/src/Messenger/SomeMessageProvider.php b/code_samples/background_tasks/src/Messenger/SomeMessageProvider.php new file mode 100644 index 0000000000..98f53c7123 --- /dev/null +++ b/code_samples/background_tasks/src/Messenger/SomeMessageProvider.php @@ -0,0 +1,14 @@ +` +php bin/console messenger:consume ibexa.messenger.transport --bus=ibexa.messenger.bus --siteaccess= ``` -In [multi-repository setups](repository_configuration.md), the worker process always works for a [SiteAccess](multisite_configuration.md#siteaccess-configuration) that you indicate by using the `--siteaccess` option, therefore you may need to run multiple workers, one for each SiteAccess. +Use the `--siteaccess` option to set the default [SiteAccess](multisite_configuration.md#siteaccess-configuration) and [repository](repository_configuration.md#defining-custom-connection) for the worker process. +The worker uses this SiteAccess for every message that doesn't have a [`SiteAccessStamp`](#siteaccessstamp). + +If a message has a `SiteAccessStamp`, the worker uses the SiteAccess from the stamp instead to processes this message. +Thanks to this, one worker process can handle messages coming from different SiteAccesses. + +In [multi-repository setups](repository_configuration.md), run one worker process for each repository. +With this setup, each worker process can connect to the right database. !!! caution "Multi-repository setups" @@ -154,19 +161,21 @@ To have a task processed in the background by [[= product_name_base =]] Messenge 1. Inject the `ibexa.messenger.bus` service as an object implementing the `Symfony\Component\Messenger\MessageBusInterface` interface. 2. Dispatch an appropriate message by using the `MessageBusInterface::dispatch()` method, exactly as described in [Symfony Messenger documentation]([[= symfony_doc =]]/messenger.html#dispatching-the-message). -``` yaml -services: - SomeClassThatSchedulesExecutionInTheBackground: - arguments: - $bus: '@ibexa.messenger.bus' -``` + ``` yaml + services: + SomeClassThatSchedulesExecutionInTheBackground: + arguments: + $bus: '@ibexa.messenger.bus' + ``` -``` php -[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 1, 19, remove_indent=True) =]] -[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 23, 24, remove_indent=True) =]] -``` + ``` php + [[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 1, 19, indent_level=1) =]] + [[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 23, 24, indent_level=1) =]] + ``` + +3. [Route the message to the background queue](#route-message-to-background-queue). -Additionally, attach message metadata by using [stamps](#stamps). +4. Additionally, attach message metadata by using [stamps](#stamps). ### Stamps @@ -184,6 +193,7 @@ You can use the following Symfony stamps: On top of the supported Symfony stamps, [[= product_name =]] provides the following ones: - [`DeduplicateStamp`](#deduplicatestamp) +- [`SiteAccessStamp`](#siteaccessstamp) #### DeduplicateStamp @@ -193,6 +203,24 @@ When you attach it to a message, the system uses a lock to ensure that only one This stamp is backported from Symfony 7. For more information, see [Symfony 7.4 documentation about message deduplication](https://symfony.com/doc/7.4//messenger.html#message-deduplication). +#### SiteAccessStamp + +[`Ibexa\Contracts\Messenger\Stamp\SiteAccessStamp`](https://example.com/add-link-when-php-api-reference-is-generated) contains the name of the [SiteAccess](siteaccess.md) that dispatched the message. + +You don't need to add this stamp manually, [[= product_name_base =]] Messenger attaches this stamp to each dispatched message automatically. +The stamp contains the SiteAccess that is current at the moment of dispatch. + +Before the worker calls the handler, it changes the configuration scope to the SiteAccess from the stamp. +The handler then reads [SiteAccess-aware configuration](multisite_configuration.md#siteaccess-configuration) for the SiteAccess that dispatched the message, and not for the SiteAccess that the worker process started with. + +!!! caution "The stamp doesn't change the current SiteAccess" + + The stamp changes the configuration scope only. + It doesn't change the SiteAccess in the `Ibexa\Core\MVC\Symfony\SiteAccess\SiteAccessServiceInterface` service. + `SiteAccessServiceInterface::getCurrent()` always returns the SiteAccess that the worker process started with, for all messages. + + To get a SiteAccess-aware value in a handler, use the [`ConfigResolverInterface` service](dynamic_configuration.md). + ## Extend Ibexa Messenger ### Register custom message and handler @@ -216,3 +244,30 @@ services: - name: messenger.message_handler bus: ibexa.messenger.bus ``` + +### Route message to background queue + +To have a message processed in the background, it must be sent to a transport queue. +[[= product_name_base =]] Messenger uses message providers instead of [Symfony `framework.messenger.routing` configuration]([[= symfony_doc =]]/messenger.html#routing-messages-to-a-transport). + +A message provider is a service that implements the [`MessageProviderInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Messenger-Transport-MessageProviderInterface.html) interface, and the `getHandledClasses()` method must return the list of message classes that [[= product_name_base =]] Messenger must send to the queue to process in the background. + +The `getHandledClasses()` method can also return a parent class or an interface. +In this case, all messages that extend this class, or implement this interface, go to the background queue. + +If no message provider returns the class of your message, the bus calls the handler immediately, in the same process that dispatches the message. + +To send `SomeMessage` to the background queue, create the following provider: + +``` php hl_lines="12" +[[= include_file("code_samples/background_tasks/src/Messenger/SomeMessageProvider.php") =]] +``` + +If you're not using service autoconfiguration, add the `ibexa.messenger.sender_message_provider` tag to the service: + +``` yaml hl_lines="4" +services: + App\Messenger\SomeMessageProvider: + tags: + - name: ibexa.messenger.sender_message_provider +``` diff --git a/mkdocs.yml b/mkdocs.yml index 835467c4bc..77248d6c0d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -989,8 +989,9 @@ extra: latest_tag_5_0: '5.0.9' symfony_doc: 'https://symfony.com/doc/5.x' - user_doc: 'https://doc.ibexa.co/projects/userguide/en/4.6' symfony_version: '5.4' + + user_doc: 'https://doc.ibexa.co/projects/userguide/en/4.6' connect_doc: 'https://doc.ibexa.co/projects/connect/en/latest' extra_css: