docs(articles): English translation of From Magento to Symfony
en/articles/magento-to-symfony/infrastructure/async.md
new file +95
−0
Queues and cron
Magento · four XML files and a publisher
<!-- communication.xml -->
<topic name="vendor.product.reindex" request="int"/>
<!-- queue_publisher.xml, queue_topology.xml,
queue_consumer.xml — three more files -->
$this->publisher->publish('vendor.product.reindex', $productId);
class ReindexConsumer
{
public function process(int $productId): void
{
//
}
}
Symfony · message, handler, routing
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
- Without a line in
routingthe message is handled synchronously, right ondispatch(). Handy in tests and for a gradual migration. - Worker:
bin/console messenger:consume async --time-limit=3600 --memory-limit=256Munder supervisor or systemd. - Messages that failed after retries sit in
failed:messenger:failed:show,messenger:failed:retry. - Put ids and scalars into messages, not entities: the message is serialized, and the worker has to re-read the entity.
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
{
//
}
}
# the schedule is run by a Messenger worker:
# bin/console messenger:consume scheduler_default
An alternative without Scheduler is a regular console command in the system crontab. For tasks that must not run in parallel on several servers, add the Lock component.