How to get all pending jobs in laravel queue on redis?
Asked Answered
I

7

40

The queue:listen was not run on a server, so some jobs were pushed (using Redis driver) but never run.

How could I count (or get all) these jobs? I did not find any artisan command to get this information.

Infield answered 15/2, 2016 at 15:11 Comment(0)
H
36

If someone is still looking for an answer, here is the way I did it:

$connection = null;
$default = 'default';

// For the delayed jobs
var_dump(
    \Queue::getRedis()
        ->connection($connection)
        ->zrange('queues:'.$default.':delayed', 0, -1)
);
    
// For the reserved jobs
var_dump(
    \Queue::getRedis()
        ->connection($connection)
        ->zrange('queues:'.$default.':reserved', 0, -1)
);

$connection is the Redis' connection name which is null by default, and the $default is the name of the queue which is default by default.

Headpin answered 11/2, 2017 at 23:46 Comment(3)
Is there a way to get only the count of reserved jobs without needing to further process/evaluate the resulting array?Linguistician
For Laravel 5.8 I had to use the lrange command instead of zrange.Twofaced
the -1 was not doing it for me... I used 99999 and worked fine.Faubert
C
38

Since Laravel 5.3 you can simply use Queue::size() (see PR).

Charissa answered 9/2, 2018 at 12:7 Comment(1)
use Queue::size('queue-name'); for specific queue.Liquescent
H
36

If someone is still looking for an answer, here is the way I did it:

$connection = null;
$default = 'default';

// For the delayed jobs
var_dump(
    \Queue::getRedis()
        ->connection($connection)
        ->zrange('queues:'.$default.':delayed', 0, -1)
);
    
// For the reserved jobs
var_dump(
    \Queue::getRedis()
        ->connection($connection)
        ->zrange('queues:'.$default.':reserved', 0, -1)
);

$connection is the Redis' connection name which is null by default, and the $default is the name of the queue which is default by default.

Headpin answered 11/2, 2017 at 23:46 Comment(3)
Is there a way to get only the count of reserved jobs without needing to further process/evaluate the resulting array?Linguistician
For Laravel 5.8 I had to use the lrange command instead of zrange.Twofaced
the -1 was not doing it for me... I used 99999 and worked fine.Faubert
F
17

You can also use the Redis Facade directly by doing this:

use Redis;

\Redis::lrange('queues:$queueName', 0, -1);

Tested in Laravel 5.6 but should work for all 5.X.

Felty answered 28/3, 2018 at 12:9 Comment(0)
S
15

If you are using redis driver for your queue, you can count all remaining jobs by name:

use Redis;

// List all keys with status (awaiting, reserved, delayed)
Redis::keys('*');

// Count by name
$queueName = 'default';
echo Redis::llen('queues:' . $queueName);

// To count by status:
echo Redis::zcount('queues:' . $queueName . ':delayed', '-inf', '+inf');
echo Redis::zcount('queues:' . $queueName . ':reserved', '-inf', '+inf');

To see the result immediately, you can use php artisan tinker and hit Redis::llen('queues:default');.

Saurel answered 1/3, 2019 at 3:37 Comment(2)
Why we need // List all keys with status (awaiting, reserved, delayed) Redis::keys('*'); On the production this can be heavy call depending on the usage?Filtrate
@ShivdhwajPandey Because I am not sure about it's performance (Redis::keys('*');), you are correct, thank you (https://mcmap.net/q/175304/-scan-vs-keys-performance-in-redis). I just listed them up here for debugging in dev or stg environment. Do you have any recommend commands in Prod env for this case? Please share us! :bow: <3Icebreaker
S
6

You can install Horizon. Laravel Horizon provides a dashboard for monitoring your queues, and allows you to do more configuration to your queue.

composer require laravel/horizon

php artisan vendor:publish --provider="Laravel\Horizon\HorizonServiceProvider"

You have to set .env config file and config/horizon.php file.

Tested with Laravel 5.6

Swaine answered 3/9, 2018 at 16:12 Comment(0)
D
1

If anybody is still looking approach for the older versions of the Laravel:

$connection = 'queue';
$queueName = 'default';

$totalQueuedLeads = Redis::connection($connection)
    ->zcount('queues:'.$queueName.':delayed' , '-inf', '+inf');
Debbidebbie answered 13/8, 2018 at 16:16 Comment(0)
F
1

I have two queues, a default queue and a low_prio queue in my laravel 5.7 project.

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class JobsOnQueue extends Command
{

    // su -c "php artisan jobs:on:queue" -s /bin/sh www-data

    protected $signature = 'jobs:on:queue';

    protected $description = 'Print jobs in redis';

    protected $lines = [];

    public function handle()
    {

        $connection = null;

        $queuename       = 'default';
        $default_delayed = \Queue::getRedis()
            ->connection($connection)
            ->zrange('queues:' . $queuename . ':delayed', -9999, 9999);

        $default_reserved = \Queue::getRedis()
            ->connection($connection)
            ->zrange('queues:' . $queuename . ':reserved', -9999, 9999);

        $queuename        = 'low_prio';
        $low_prio_delayed = \Queue::getRedis()
            ->connection($connection)
            ->zrange('queues:' . $queuename . ':delayed', -9999, 9999);

        $low_prio_reserved = \Queue::getRedis()
            ->connection($connection)
            ->zrange('queues:' . $queuename . ':reserved', -9999, 9999);

        $this->getQueueData('default delayed', $default_delayed);
        $this->getQueueData('default reserved', $default_reserved);
        $this->getQueueData('low prio delayed', $low_prio_delayed);
        $this->getQueueData('low prio reserved', $low_prio_reserved);

        $this->info(join("\n", $this->lines));

    }

    private function getQueueData($title, $arr)
    {
        $this->lines[] = "*** $title ***";
        if (count($arr) == 0) {
            $this->lines[] = "Nothing on queue";
            $this->lines[] = "";
            return;
        }

        foreach ($arr as $json) {
            $queue = json_decode($json);
            $data  = $queue->data;

            if (isset($data) && isset($data->command)) {
                $this->getCommands($data->command);
            }
        }
        $this->lines[] = "";

    }

    private function getCommands($serialized)
    {

        $readable = str_replace(
            'O:43:"Illuminate\Foundation\Console\QueuedCommand',
            'O:33:"App\Support\ReadableQueuedCommand',
            $serialized);

        $readable = unserialize($readable);
        $command  = $readable->getData();

        $attribs = [];
        $options = $command[1];
        foreach ($options as $key => $value) {
            $attribs[] = $key . '=' . $value;
        }

        $this->lines[] = $command[0] . ' ' . join(" - ", $attribs);
    }

}

The ReadableQueuedCommand looks like this

<?php

namespace App\Support;

use Illuminate\Foundation\Console\QueuedCommand;

class ReadableQueuedCommand extends QueuedCommand
{
    public function getData()
    {
        return $this->data;
    }
}

The artisan command then lists all in queue

> php artisan jobs:on:queue

*** default delayed ***
Nothing on queue

*** default reserved ***
Nothing on queue

*** low prio delayed ***
Nothing on queue

*** low prio reserved ***
oppty:time:profile --by-dataset=2
oppty:on:reset:pages --by-dataset=2

Faubert answered 23/9, 2020 at 15:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.