我几天前已经实现了一个工作队列,我遇到了重复问题,我目前正在使用Redis并遵循Laravel的官方教程。
就我而言,只要有人进入主页,就会将作业发送到队列,让我们举个例子:
HomeController's index()
:
public function index()
{
if(/*condition*/){
//UpdateServer being the job
$this->dispatch(new UpdateServer());
}
}
由于此任务大约需要10秒钟才能完成,如果在处理任务时对我的主页有n个请求,队列中将会有更多相同的作业,从而导致我的数据库出现意外结果。
所以我的问题是,有没有办法知道某个职位是否已经在队列中?
答案 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);
现在,您可以评估所需的输入是否在这些队列之一中并采取相应的行动。