DEV Community

F.R Michel
F.R Michel

Posted on

Use symfony/messenger without supervisor

Symfony messenger use Supervisor to keep workers running but not all web hosting have a supervisor.

By default, the command will run forever and handle 10 messages before exiting with memory limit(128M) :

bin/console messenger:consume async --limit=10 --memory-limit=128M
Enter fullscreen mode Exit fullscreen mode

To work around this problem, we will use cronjobs but we don't let workers run forever.
For that we will listen on the event WorkerRunningEvent :

<?php


namespace App\Event;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\Event\WorkerRunningEvent;

/**
 * Class ExtractFailedEvent
 * @package App\Event
 */
class CronRunningEvent implements EventSubscriberInterface
{
    public function onWorkerRunning(WorkerRunningEvent $event): void
    {
        if ($event->isWorkerIdle()) {
            $event->getWorker()->stop();
        }
    }

    /**
     * @return array<string>
     */
    public static function getSubscribedEvents()
    {
        return [
            WorkerRunningEvent::class => 'onWorkerRunning',
        ];
    }
}

Enter fullscreen mode Exit fullscreen mode

Method isWorkerIdle() return true when no message has been received by the worker.
If no message has been received , we stop the worker

To finish, set up a cron job to run evry minute

* * * * * bin/console messenger:consume async --memory-limit=128M
Enter fullscreen mode Exit fullscreen mode

Simple and easy!

Top comments (8)

Collapse
 
damienalexandre profile image
Damien Alexandre

I fear you are going to saturate your server with consumers if your message queue gets filled with messages. As it's never empty, the worker never stops, and you create a new one every minute - without any limit / safeguard.

You could leverage the Lock component to make sure there are never two consumers running at the same time.

Collapse
 
ehraid profile image
Dennis

Actually it won't keep going seeing as he used --limit=10. So it'd stop at 10 anyway and can't continually keep going if the message queue gets full of messages. So I suppose it's more of a "Good morning. Wake up. Check phone for messages. Only go through 10 messages. Stop. Go back to bed till the next minute."

Collapse
 
sebastianrozmus profile image
sebastianrozmus

I agree with Damien. To avoid that I would recommend to add --time-limit=60

Collapse
 
icolomina profile image
Nacho Colomina Torregrosa

Yes, i agree, it would resolve the problem of having so many workers if there are always messages

Collapse
 
parijke profile image
Paul Rijke

Brilliant trick... I actually postponed using Messenger because of the worker problem on my shared hosting.

Collapse
 
fadymr profile image
F.R Michel

I had the same problem.

Collapse
 
chrishow2 profile image
Chrishow2

Excellent and elegant...I solved mi problem in half a minute. Thanks a lot man!

Collapse
 
ehraid profile image
Dennis

In the docs it says:

To properly stop a worker, throw an instance of StopWorkerException.