docs(articles): From Magento to Symfony, a requalification guide grouped into sections
uk/articles/magento-to-symfony/infrastructure/async.md
новий файл +95
−0
Черги та cron
Magento · чотири XML і publisher
<!-- communication.xml -->
<topic name="vendor.product.reindex" request="int"/>
<!-- queue_publisher.xml, queue_topology.xml,
queue_consumer.xml — ще три файли -->
$this->publisher->publish('vendor.product.reindex', $productId);
class ReindexConsumer
{
public function process(int $productId): void
{
//
}
}
Symfony · повідомлення, обробник, маршрут
final class ReindexProduct
{
public function __construct(public readonly int $productId) {}
}
#[AsMessageHandler]
final class ReindexProductHandler
{
public function __invoke(ReindexProduct $message): void
{
//
}
}
$this->bus->dispatch(new ReindexProduct($product->getId()));
Symfony · config/packages/messenger.yaml
framework:
messenger:
failure_transport: failed
transports:
async:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%' # doctrine://, amqp://, redis://
retry_strategy: { max_retries: 3, delay: 1000, multiplier: 2 }
failed: 'doctrine://default?queue_name=failed'
routing:
App\Message\ReindexProduct: async
- Без рядка в
routingповідомлення обробиться синхронно, одразу приdispatch(). Зручно в тестах і для поступового переходу. - Воркер:
bin/console messenger:consume async --time-limit=3600 --memory-limit=256Mпід supervisor або systemd. - Провалені після ретраїв повідомлення лежать у
failed:messenger:failed:show,messenger:failed:retry. - У повідомлення кладуть id і скаляри, а не сутності: повідомлення серіалізується, а сутність у воркері треба перечитати.
crontab.xml → Scheduler
Magento · crontab.xml
<group id="default">
<job name="vendor_cleanup_quotes"
instance="Vendor\Sales\Cron\CleanupQuotes"
method="execute">
<schedule>0 3 * * *</schedule>
</job>
</group>
Symfony · symfony/scheduler
use Symfony\Component\Scheduler\Attribute\AsCronTask;
#[AsCronTask('0 3 * * *')]
final class CleanupExpiredQuotes
{
public function __invoke(): void
{
//
}
}
# запуск розкладу — це воркер Messenger:
# bin/console messenger:consume scheduler_default
Альтернатива без Scheduler — звичайна консольна команда в системному crontab. Для задач, які не можна запускати паралельно на кількох серверах, додайте компонент Lock.