【问题标题】:Check if Job is already in queue using Laravel 5 and Redis使用 Laravel 5 和 Redis 检查作业是否已经在队列中
【发布时间】:2015-10-23 19:04:06
【问题描述】:

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

在我的例子中,每当有人访问主页时,都会将作业发送到队列中,让我们举这个例子:

HomeController 的 index()

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

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

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

【问题讨论】:

    标签: redis queue laravel-5 jobs


    【解决方案1】:

    我知道这是一个老问题,但我发现自己一次又一次地从 Google 回到这里,所以我想给它一个答案。我想要一种简单的方法来在仪表板上查看我的 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 的队列。

    【讨论】:

      【解决方案2】:

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

      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);
      

      现在您可以评估您想要的输入是否在这些队列之一中并采取相应措施。

      【讨论】:

        【解决方案3】:

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

        Laravel 8 开始有了“独特的工作”功能 - https://laravel.com/docs/8.x/queues#unique-jobs

        【讨论】:

        • Sweet 在宣布 Laravel 8 时不知何故错过了这一点!谢谢!
        【解决方案4】:

        您可以在作业处理函数中执行此操作,如果安排了另一个相同的作业,则可以跳过工作

        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
        }
        

        【讨论】:

          猜你喜欢
          • 2015-04-18
          • 2015-04-19
          • 1970-01-01
          • 2013-05-06
          • 1970-01-01
          • 2010-12-07
          • 2018-06-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多