Черги та cron

← Черги та cron

Ashterix

docs(articles): From Magento to Symfony, a requalification guide grouped into sections

uk/articles/magento-to-symfony/infrastructure/async.md новий файл +95 −0

1 + # Черги та cron
2 +
3 + **Magento** · чотири XML і publisher
4 +
5 + ```xml
6 + <!-- communication.xml -->
7 + <topic name="vendor.product.reindex" request="int"/>
8 + <!-- queue_publisher.xml, queue_topology.xml,
9 + queue_consumer.xml — ще три файли -->
10 + ```
11 + ```php
12 + $this->publisher->publish('vendor.product.reindex', $productId);
13 +
14 + class ReindexConsumer
15 + {
16 + public function process(int $productId): void
17 + {
18 + //
19 + }
20 + }
21 + ```
22 +
23 + **Symfony** · повідомлення, обробник, маршрут
24 +
25 + ```php
26 + final class ReindexProduct
27 + {
28 + public function __construct(public readonly int $productId) {}
29 + }
30 +
31 + #[AsMessageHandler]
32 + final class ReindexProductHandler
33 + {
34 + public function __invoke(ReindexProduct $message): void
35 + {
36 + //
37 + }
38 + }
39 +
40 + $this->bus->dispatch(new ReindexProduct($product->getId()));
41 + ```
42 +
43 + **Symfony** · config/packages/messenger.yaml
44 +
45 + ```yaml
46 + framework:
47 + messenger:
48 + failure_transport: failed
49 + transports:
50 + async:
51 + dsn: '%env(MESSENGER_TRANSPORT_DSN)%' # doctrine://, amqp://, redis://
52 + retry_strategy: { max_retries: 3, delay: 1000, multiplier: 2 }
53 + failed: 'doctrine://default?queue_name=failed'
54 + routing:
55 + App\Message\ReindexProduct: async
56 + ```
57 +
58 + - Без рядка в `routing` повідомлення обробиться синхронно, одразу при `dispatch()`. Зручно в тестах і для поступового переходу.
59 + - Воркер: `bin/console messenger:consume async --time-limit=3600 --memory-limit=256M` під supervisor або systemd.
60 + - Провалені після ретраїв повідомлення лежать у `failed`: `messenger:failed:show`, `messenger:failed:retry`.
61 + - У повідомлення кладуть id і скаляри, а не сутності: повідомлення серіалізується, а сутність у воркері треба перечитати.
62 +
63 + ## crontab.xml → Scheduler
64 +
65 + **Magento** · crontab.xml
66 +
67 + ```xml
68 + <group id="default">
69 + <job name="vendor_cleanup_quotes"
70 + instance="Vendor\Sales\Cron\CleanupQuotes"
71 + method="execute">
72 + <schedule>0 3 * * *</schedule>
73 + </job>
74 + </group>
75 + ```
76 +
77 + **Symfony** · symfony/scheduler
78 +
79 + ```php
80 + use Symfony\Component\Scheduler\Attribute\AsCronTask;
81 +
82 + #[AsCronTask('0 3 * * *')]
83 + final class CleanupExpiredQuotes
84 + {
85 + public function __invoke(): void
86 + {
87 + //
88 + }
89 + }
90 +
91 + # запуск розкладу — це воркер Messenger:
92 + # bin/console messenger:consume scheduler_default
93 + ```
94 +
95 + Альтернатива без Scheduler — звичайна консольна команда в системному crontab. Для задач, які не можна запускати паралельно на кількох серверах, додайте компонент Lock.