Skip to content

Commit 9d92854

Browse files
authored
Described stamps for Ibexa Messenger (#3272)
* Described stamps for Ibexa Messenger * Fixed typos * Link to Symfony messages
1 parent 1131f70 commit 9d92854

5 files changed

Lines changed: 78 additions & 25 deletions

File tree

code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,25 @@
22

33
namespace App\Dispatcher;
44

5-
use Ibexa\Bundle\Messenger\Stamp\DeduplicateStamp;
6-
use Symfony\Component\Messenger\Envelope;
5+
use Ibexa\Contracts\Core\Repository\PermissionResolver;
6+
use Ibexa\Contracts\Messenger\Stamp\SudoStamp;
7+
use Ibexa\Contracts\Messenger\Stamp\UserPermissionStamp;
78
use Symfony\Component\Messenger\MessageBusInterface;
89

910
final readonly class SomeClassThatSchedulesExecutionInTheBackground
1011
{
11-
public function __construct(private MessageBusInterface $bus)
12-
{
12+
public function __construct(
13+
private MessageBusInterface $bus,
14+
private PermissionResolver $permissionResolver,
15+
) {
1316
}
1417

1518
public function schedule(object $message): void
1619
{
17-
// Dispatch directly. Message is wrapped with envelope without any stamps.
1820
$this->bus->dispatch($message);
1921

20-
// Alternatively, wrap with stamps. In this case, DeduplicateStamp ensures
21-
// that if similar command exists in the queue (or is being processed)
22-
// it will not be queued again.
23-
$envelope = Envelope::wrap(
24-
$message,
25-
[new DeduplicateStamp('command-name-1')]
26-
);
27-
28-
$this->bus->dispatch($envelope);
22+
$currentUserId = $this->permissionResolver->getCurrentUserReference()->getUserId();
23+
$this->bus->dispatch($message, [new UserPermissionStamp($currentUserId)]);
24+
$this->bus->dispatch($message, [new SudoStamp()]);
2925
}
3026
}

deptrac.baseline.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,6 @@ deptrac:
120120
- Ibexa\Discounts\Value\AbstractDiscountExpressionAware
121121
App\Discounts\Rule\PurchasingPowerParityRuleFactory:
122122
- Ibexa\Discounts\Repository\DiscountRule\DiscountRuleFactoryInterface
123-
App\Dispatcher\SomeClassThatSchedulesExecutionInTheBackground:
124-
- Ibexa\Bundle\Messenger\Stamp\DeduplicateStamp
125123
App\EventListener\TextAnchorMenuTabListener:
126124
- Ibexa\AdminUi\Menu\ContentEditAnchorMenuBuilder
127125
- Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent

docs/content_management/data_migration/importing_data.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ You can run a set of one or more similar migration steps multiple times by using
8888

8989
A repeatable migration performs the defined migration steps as many times as specified:
9090

91-
- with an [interation counter](#repeatable-steps-with-iteration-counter), mimicking the behavior of a [`for` loop](https://www.php.net/manual/en/control-structures.for.php)
91+
- with an [iteration counter](#repeatable-steps-with-iteration-counter), mimicking the behavior of a [`for` loop](https://www.php.net/manual/en/control-structures.for.php)
9292
- with a [list of items](#repeatable-steps-with-items), mimicking the behavior of a [`foreach` loop](https://www.php.net/manual/en/control-structures.foreach.php)
9393

9494
!!! tip

docs/infrastructure_and_maintenance/background_tasks.md

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ These messages are stored in a queue and picked up by a background worker, which
2121
The process works as follows:
2222

2323
1. A message PHP object is dispatched, for example, `ProductPriceReindex`.
24-
2. The message is wrapped in an envelope, which may contain additional metadata, called stamps, for example, `DeduplicateStamp`.
24+
2. The message is wrapped in an envelope, which may contain additional metadata, called [stamps](#stamps).
2525
3. The message is placed in the transport queue.
2626
It can be a Doctrine table, a Redis/Valkey queue, and so on.
2727
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.
@@ -92,25 +92,83 @@ For more information, see [Symfony production recommendation for the Messenger c
9292

9393
If you deploy your application on [[= product_name_cloud =]], using [Workers](https://fixed.docs.upsun.com/guides/symfony/workers.html) is recommended.
9494

95-
### Dispatch message
95+
## Dispatch message
9696

97-
Dispatch a message from your code like in the following example:
97+
To have a task processed in the background, dispatch an appropriate message by using the `\Symfony\Component\Messenger\MessageBusInterfac\MessageBusInterface::dispatch()` method, exactly as described in [Symfony Messenger documentation]([[= symfony_doc =]]/messenger.html#dispatching-the-message):
9898

9999
``` php
100-
[[= include_code("code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php") =]]
100+
[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 1, 3) =]]
101+
102+
[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 8, 13) =]]
103+
[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 15, 20) =]]
104+
[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 25, 26) =]]
101105
```
102106

103-
### Register handler
107+
Additionally, attach message metadata by using [stamps](#stamps).
108+
109+
### Stamps
110+
111+
You can attach [Stamps]([[= symfony_doc =]]/messenger.html#envelopes-stamps) to a message envelope to add additional metadata and control how the message is processed.
112+
113+
Use [Stamps available in Symfony](https://github.com/symfony/symfony/tree/[[= symfony_version =]]/src/Symfony/Component/Messenger/Stamp), and combine them with the ones provided by [[= product_name =]]:
114+
115+
- [SudoStamp](#sudostamp)
116+
- [UserPermissionStamp](#userpermissionstamp)
117+
118+
#### SudoStamp
119+
120+
[`SudoStamp`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Messenger-Stamp-SudoStamp.html) causes the handler to [use sudo mode](php_api.md#using-sudo), bypassing all permission checks when processing the message.
121+
122+
It's automatically attached to every dispatched message.
104123

105-
Create the handler class:
124+
!!! caution
125+
126+
Starting with Ibexa DXP 5.0.9, the behavior of automatically attaching a `SudoStamp` to every message is deprecated and will be removed in 6.0.
127+
For messages that should be processed without taking permissions into account, always attach the `SudoStamp` manually to keep your code forward-compatible.
128+
129+
The following example shows how you can attach the `SudoStamp` to the message:
130+
131+
``` php
132+
[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 6, 6, remove_indent=True) =]]
133+
[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 8, 9, remove_indent=True) =]]
134+
135+
[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 24, 24, remove_indent=True) =]]
136+
```
137+
138+
#### UserPermissionStamp
139+
140+
[`UserPermissionStamp`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Messenger-Stamp-UserPermissionStamp.html) allows you to [set the repository user](php_api.md#setting-the-repository-user) to process the message.
141+
When the user is set, handlers execute actions on their behalf and take their permissions into account.
142+
143+
If you don't attach this stamp, the messages are processed by the default repository user called anonymous user.
144+
By combing this stamp with [`SudoStamp`](#sudostamp), you can set the repository user and skip the permission checks at the same time.
145+
146+
The following example shows how you can use `UserPermissionStamp` to preserve the current repository user after the message is dispatched.
147+
148+
``` php
149+
[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 5, 5, remove_indent=True) =]]
150+
[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 7, 9, remove_indent=True) =]]
151+
152+
[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 22, 23, remove_indent=True) =]]
153+
```
154+
155+
## Extend Ibexa Messenger
156+
157+
### Register custom message and handler
158+
159+
To handle additional use cases with background tasks, you can create [custom message and handler class]([[= symfony_doc =]]/messenger.html#creating-a-message-handler):
160+
161+
``` php
162+
[[= include_code('code_samples/background_tasks/src/Message/SomeMessage.php') =]]
163+
```
106164

107165
``` php
108166
[[= include_code("code_samples/background_tasks/src/MessageHandler/SomeHandler.php") =]]
109167
```
110168

111-
Add a service definition to `config/services.yaml`:
169+
Add a service definition to `config/services.yaml` and set the `bus` to `ibexa.messenger.bus`:
112170

113-
``` yaml
171+
``` yaml hl_lines="4-5"
114172
services:
115173
App\MessageHandler\SomeHandler:
116174
tags:

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,7 @@ extra:
10421042
latest_tag_4_6: '4.6.31'
10431043
latest_tag_5_0: '5.0.9'
10441044

1045+
symfony_version: '7.4'
10451046
symfony_doc: 'https://symfony.com/doc/7.4'
10461047
user_doc: 'https://doc.ibexa.co/projects/userguide/en/5.0'
10471048
connect_doc: 'https://doc.ibexa.co/projects/connect/en/latest'

0 commit comments

Comments
 (0)