Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php declare(strict_types=1);

namespace App\Messenger;

use App\Message\SomeMessage;
use Ibexa\Contracts\Messenger\Transport\MessageProviderInterface;

final class SomeMessageProvider implements MessageProviderInterface
{
public function getHandledClasses(): iterable
{
return [SomeMessage::class];
}
}
4 changes: 2 additions & 2 deletions docs/administration/configuration/dynamic_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

## ConfigResolver

Dynamic configuration is handled by a ConfigResolver.
Dynamic configuration is handled by the [`ConfigResolverInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-SiteAccess-ConfigResolverInterface.html).

Check notice on line 9 in docs/administration/configuration/dynamic_configuration.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/administration/configuration/dynamic_configuration.md#L9

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/administration/configuration/dynamic_configuration.md", "range": {"start": {"line": 9, "column": 23}}}, "severity": "INFO"}

It exposes the `hasParameter()` and `getParameter()` methods.
You can use them to check the different *scopes* available for a given *namespace* to find the appropriate parameter.
Expand Down Expand Up @@ -68,7 +68,7 @@
arguments: ['@ibexa.config.resolver']
```

You can also use the [autowire feature]([[= symfony_doc =]]/service_container/autowiring.html), by type hinting against ConfigResolverInterface.
You can also use the [autowire feature]([[= symfony_doc =]]/service_container/autowiring.html), by type hinting against [`ConfigResolverInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Core-SiteAccess-ConfigResolverInterface.html).

Check failure on line 71 in docs/administration/configuration/dynamic_configuration.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/administration/configuration/dynamic_configuration.md#L71

[Ibexa.Spellcheck] Did you really mean 'autowire'?
Raw output
{"message": "[Ibexa.Spellcheck] Did you really mean 'autowire'?", "location": {"path": "docs/administration/configuration/dynamic_configuration.md", "range": {"start": {"line": 71, "column": 23}}}, "severity": "ERROR"}

For more information about dependency injection, see [Service container](php_api.md#service-container).

Expand Down
83 changes: 69 additions & 14 deletions docs/infrastructure_and_maintenance/background_tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@

1. A message PHP object is dispatched, for example, `ProductPriceReindex`.
2. The message is wrapped in an envelope, which may contain additional metadata, called [stamps](#stamps).
3. The message is placed in the transport queue.
3. The message is placed in the [transport queue](#route-message-to-background-queue).

Check notice on line 97 in docs/infrastructure_and_maintenance/background_tasks.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/background_tasks.md#L97

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/infrastructure_and_maintenance/background_tasks.md", "range": {"start": {"line": 97, "column": 16}}}, "severity": "INFO"}
It can be a Doctrine table, a Redis/Valkey queue, and so on.
4. A worker process continuously reads messages from the queue, pulls them into the default bus `ibexa.messenger.bus` and assigns them to the right handler.
5. A handler service processes the message (executes the command).
Expand Down Expand Up @@ -134,10 +134,17 @@
Use a process manager of your choice to run the following command, or make it start together with the server:

``` bash
php bin/console messenger:consume ibexa.messenger.transport --bus=ibexa.messenger.bus --siteaccess=<OPTIONAL>`
php bin/console messenger:consume ibexa.messenger.transport --bus=ibexa.messenger.bus --siteaccess=<OPTIONAL>
```

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"

Expand All @@ -154,19 +161,21 @@
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

Expand All @@ -184,6 +193,7 @@
On top of the supported Symfony stamps, [[= product_name =]] provides the following ones:

- [`DeduplicateStamp`](#deduplicatestamp)
- [`SiteAccessStamp`](#siteaccessstamp)

#### DeduplicateStamp

Expand All @@ -193,6 +203,24 @@
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
Expand All @@ -216,3 +244,30 @@
- 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.

Check notice on line 250 in docs/infrastructure_and_maintenance/background_tasks.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/background_tasks.md#L250

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/infrastructure_and_maintenance/background_tasks.md", "range": {"start": {"line": 250, "column": 56}}}, "severity": "INFO"}
[[= 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:

Check notice on line 266 in docs/infrastructure_and_maintenance/background_tasks.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/background_tasks.md#L266

[Ibexa.ByUsing] Prefer 'by using' or 'with' to plain 'using'.
Raw output
{"message": "[Ibexa.ByUsing] Prefer 'by using' or 'with' to plain 'using'.", "location": {"path": "docs/infrastructure_and_maintenance/background_tasks.md", "range": {"start": {"line": 266, "column": 11}}}, "severity": "INFO"}

``` yaml hl_lines="4"
services:
App\Messenger\SomeMessageProvider:
tags:
- name: ibexa.messenger.sender_message_provider

Check notice on line 272 in docs/infrastructure_and_maintenance/background_tasks.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/background_tasks.md#L272

[Ibexa.Lists] Verify list formatting: Full sentences should start with uppercase and end with a period. Sentence fragments should start with lowercase and have no period.
Raw output
{"message": "[Ibexa.Lists] Verify list formatting: Full sentences should start with uppercase and end with a period. Sentence fragments should start with lowercase and have no period.", "location": {"path": "docs/infrastructure_and_maintenance/background_tasks.md", "range": {"start": {"line": 272, "column": 1}}}, "severity": "INFO"}
```
3 changes: 2 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading