2

Ive Laravel queue running but on Database connection, here is the config:

'database' => [
    'driver' => 'database',
    'connection' => 'mysql',
    'table' => 'jobs',
    'queue' => 'default',
    'retry_after' => 190,
    'block_for' => 0,
]

This is how I run it:

php artisan queue:work --queue=xyz_queue > storage/logs/queue.log

On the redis CLI, this is what is happening every second:

enter image description here

1 Answer 1

1

It is normal and expected behavior. According to the documentation

Since queue workers are long-lived processes, they will not pick up changes to your code without being restarted. So, the simplest way to deploy an application using queue workers is to restart the workers during your deployment process. You may gracefully restart all of the workers by issuing the queue:restart command: php artisan queue:restart

This command will instruct all queue workers to gracefully "die" after they finish processing their current job so that no existing jobs are lost.

  • What queue:restart does is that setting current timestamp to the value of illuminate:queue:restart key.
  • When the queues are about to be consumed by the processes (php artisan queue:work) it gets that timestamp value from illuminate:queue:restart key and after the job is about to be completed it gets the value again from the same key.
  • It compares whether the the value before the job is processed is same as the after the job is processed.
  • If it is different, then it will stop long-lived process.

It is an efficient way(since Redis is super fast for this kind of scenarios) to detect whether the code is changed and should the jobs should be updated for this code change.

The reason it saves the value into the Redis, "most probably" your cache driver is Redis. If you change it to file then it will be saving in the file instead and making the get request to that file.

Here are the related methods;

protected function stopIfNecessary(WorkerOptions $options, $lastRestart, $job = null)
{
    if ($this->shouldQuit) {
        $this->stop();
    } elseif ($this->memoryExceeded($options->memory)) {
        $this->stop(12);
    } elseif ($this->queueShouldRestart($lastRestart)) {
        $this->stop();
    } elseif ($options->stopWhenEmpty && is_null($job)) {
        $this->stop();
    }
}

protected function queueShouldRestart($lastRestart)
{
    return $this->getTimestampOfLastQueueRestart() != $lastRestart;
}

protected function getTimestampOfLastQueueRestart()
{
    if ($this->cache) {
        return $this->cache->get('illuminate:queue:restart');
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

so it will check every sec illuminate:queue:restart key value in Redis even when there is no job to perform?
Also, yu said It is an efficient way to detect whether the code is changed and should the jobs should be updated for this code change, however the queue:work is not supposed to detect any code change. Isnt that the whole point of queue:work as a daemon?
It may execute more than 1 in a second and multiplied with number of processes. If you have 1000 and there is no sleep option set in queue:work - then you can see maybe 1000+ in a second.(even a small instance redis can handle 100K commands in a second, this one is harmless) Since they are long running processes, the framework(php maybe) is probably caching the same part of the class for performance. They are trying to detect code change while while they are "processing" the job -it is a good way i think. No need to signal manually to warn framework about "i changed the code". @RaheelHasan
@RaheelHasan 1000+ may depend on number of processes and how many instances are connected and what is the sleep etc but it won't be less. As you said, if it is fine for your business rules then totally fine. Glad it helped.
@RaheelHasan i never used/need block_for but it is only "redis-available" option since it uses BLPOP command . redis.io/commands/blpop
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.