Queues and cron

← Queues and cron

Ashterix

docs(articles): SEO titles, intros and a section preview image for From Magento to Symfony

en/articles/magento-to-symfony/infrastructure/async.md +6 −0

Queues and cron

Symfony Messenger replaces Magento queues and their four XML files: a message class, a handler and one routing line. Scheduled tasks use the Scheduler component or the system 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 routing the message is handled synchronously, right on dispatch(). Handy in tests and for a gradual migration.
  • Worker: bin/console messenger:consume async --time-limit=3600 --memory-limit=256M under 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.