MisterCat
MisterCat

Reputation: 1631

What is the difference queue:work and queue:listen

I can't understand what's the difference between Laravel queue:work and Laravel queue:listen

I can see that:

But still don't get it, because I've tried both, both will run queue if there is any new queue ("work option" not just running once)

I'm not talking about the daemon option. Just these both.

when i ran queue:work it works like listen

Upvotes: 61

Views: 55215

Answers (5)

hassan
hassan

Reputation: 8288

Note: Not sure if this is the same behavior in the previous versions, but this answer is about Laravel 11

The short answer: The queue:listen command is a wrapper for the queue:work command that keep invokes the queue:work command in a while loop. So it is not about that work is caching the whole app and listen does not.

Internally, the queue:listen is creating a sub-process that invokes the queue:work command.

The call stack will be something like the following:

ListenCommand@handle > Listener@listen  
Listener@listen > Listener@makeProcess  
Listener@makeProcess > Listener@createCommand

The createCommand method is creating a queue:work command, while makeProcess method is creating the command then run it as a Process.

// ./src/Illuminate/Queue/Listener.php

// ...

protected function createCommand($connection, $queue, ListenerOptions $options)
{
    return array_filter([
        $this->phpBinary(),
        $this->artisanBinary(),
        'queue:work',
        $connection,
        '--once',
        "--name={$options->name}",
        "--queue={$queue}",
        "--backoff={$options->backoff}",
        "--memory={$options->memory}",
        "--sleep={$options->sleep}",
        "--tries={$options->maxTries}",
        $options->force ? '--force' : null,
    ], function ($value) {
        return ! is_null($value);
    });
}

Within the Listener@listen method, there is a while loop that will keep invoking a new child process of the queue:work command. To validate this, you can run the following command in Linux:

ps -ef

The output should have something like:

...
747 root      0:00 php artisan queue:listen --memory=800 --timeout=0
1671 root      0:00 /usr/local/bin/php artisan queue:work --once --name=default --queue=default --backoff=0 --memory=800 --sleep=3 --tries=1
...

While in my case, the root process ID is 747, and the child process ID will keep changing according to the mentioned while loop

Upvotes: 1

Ohgodwhy
Ohgodwhy

Reputation: 50787

Until Laravel 5.2 you had :listen and :work.

Work would process the first job in the queue.

Listen would process all jobs as they came through.

In Laravel 5.3+ this is no longer the case. Listen still exists, but it is deprecated and slated for removal in 5.5. You should prefer :work now.

Work now process jobs one after the other, but have a plethora of options you can configure.

Edit

The above was true at the time of the posting, but since then things have been changed a bit.

queue:work should be preferred when you want your queue's to run as a daemon. This would be a long-lived process that would be beneficial where performance was an issue. This will use a cached version of the application and does not re-bootstrap the application every time a job is processed.

queue:listen should be used when you don't care about performance or you don't want to have to restart the queue after making changes to the code.

  • They'll both pop jobs off the queue 1-by-1 as received.
  • They both share almost the exact same options that can be passed to them.

Upvotes: 73

ShahinSorkh
ShahinSorkh

Reputation: 651

In Laravel 5.3+ queue:work runs a daemon listener. It could in 5.2 as well if you specified the --daemon flag. A daemon work boots the framework one time and then processes jobs repeatedly. The queue:listen command runs a queue:work --once sub-process in a loop which boots the framework each iteration.

queue:work should pretty much always be used in production as it's much more efficient and uses less RAM. However; you need to restart it after each core change. queue:listen is useful for development and local environments because you don't have to restart it after code changes (because the framework is booting fresh each job).

from here

Upvotes: 23

Khaled karam
Khaled karam

Reputation: 26

There are two different issues listed.

There is artisan queue:work and artisan queue:listen

queue:work will simply pop off the next job in the queue, and process only that one job. This is a 'one off' command that will return to the command prompt once the one queue command is processed. queue:listen will listen to the queue, and continue to process any queue commands it receives. This will continue running indefinitely until you stop it. In Laravel >=4.2 there was a --daemon command added. The way it works is simply keeps running the queues directly, rather than rebooting the entire framework after every queue is processed. This is an optional command that significantly reduces the memory and cpu requirements of your queue.

The important point with the --daemon command is that when you upgrade your application, you need to specifically restart your queue with queue:restart, otherwise you could potentially get all sorts of strange errors as your queue would still have the old code in memory.

So to answer your question "Which command should I use for running my daemons?" - the answer is almost always queue:work --daemon

Upvotes: 2

Erik Berkun-Drevnig
Erik Berkun-Drevnig

Reputation: 2356

The queue:work Artisan command includes a --daemon option for forcing the queue worker to continue processing jobs without ever re-booting the framework. This results in a significant reduction of CPU usage when compared to the queue:listen command:

As you can see, the queue:work job supports most of the same options available to queue:listen. You may use the php artisan help queue:work job to view all of the available options.

https://laravel.com/docs/5.1/queues#running-the-queue-listener

Upvotes: 2

Related Questions