使用Laravel 5和Redis检查作业是否已在队列中

时间:2015-08-01 01:41:20

标签: redis queue laravel-5 jobs

我几天前已经实现了一个工作队列,我遇到了重复问题,我目前正在使用Redis并遵循Laravel的官方教程。

就我而言,只要有人进入主页,就会将作业发送到队列,让我们举个例子:

HomeController's index()

public function index()
{
    if(/*condition*/){
          //UpdateServer being the job
          $this->dispatch(new UpdateServer());
    }
}

由于此任务大约需要10秒钟才能完成,如果在处理任务时对我的主页有n个请求,队列中将会有更多相同的作业,从而导致我的数据库出现意外结果。

所以我的问题是,有没有办法知道某个职位是否已经在队列中?

4 个答案:

答案 0 :(得分:8)

我知道这是一个老问题,但我发现自己一次又一次地从谷歌回来,所以我想给它一个答案。我想要一种简单的方法来查看仪表板上Laravel应用程序内队列中的作业,并使用以下代码。

$thejobs = array();

// Get the number of jobs on the queue
$numJobs = Redis::connection()->llen('queues:default');

// Here we select details for up to 1000 jobs
$jobs = Redis::connection()->lrange('queues:default', 0, 1000);

// I wanted to clean up the data a bit
// you could use var_dump to see what it looks like before this
// var_dump($jobs);
foreach ($jobs as $job) {

    // Each job here is in json format so decode to object form
    $tmpdata = json_decode($job);
    $data = $tmpdata->data;

    // I wanted to just get the command so I stripped away App\Jobs at the start
    $command = $this->get_string_between($data->command, '"App\Jobs\\', '"');
    $id = $tmpdata->id;

    // Could be good to see the number of attempts
    $attempts = $tmpdata->attempts;
    $thejobs[] = array($command, $id, $attempts);
}

// Now you can use the data and compare it or check if your job is already in queue

我不建议这样做,尤其是在页面加载时,比如op已完成的索引页面。如果您需要使用此代码来检查作业是否正在运行,则很可能需要重新考虑您的工作方式。

答案特定于运行Redis的队列。

答案 1 :(得分:2)

我知道这是一个很老的问题,但我正在为未来的 Google 用户回答这个问题。

Laravel 8 开始,就有了“Unique Jobs”功能 - https://laravel.com/docs/8.x/queues#unique-jobs

答案 2 :(得分:0)

您可以在作业处理功能中执行此操作,如果计划了另一个相同的作业,则可以跳过工作

public function handle()
{
    $queue = \DB::table(config('queue.connections.database.table'))->orderBy('id')->get();
    foreach ($queue as $job){
        $payload = json_decode($job->payload,true);
        if($payload['displayName'] == self::class && $job->attempts == 0){
            // same job in queue, skip
            return ;
        }
    }

    // do the work
}

答案 3 :(得分:0)

对于任何想知道为什么的人

Queue::size('queueName');

大小与

不同
Redis::llen('queues:queueName');

因为Laravel使用3条记录来计算队列的大小,所以如果您想要队列中真实的作业数,则必须执行以下操作:

Redis::lrange('queues:queueName', 0, -1);
Redis::zrange('queues:queueName:delayed', 0, -1);
Redis::zrange('queues:queueName:reserved', 0, -1);

现在,您可以评估所需的输入是否在这些队列之一中并采取相应的行动。