如何在单个作业的流程之间增加延迟?

时间:2018-12-16 04:45:18

标签: laravel

让我说我有这份工作:

class DeleteInstagramImage implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public  $tries  =  2;

    public function handle()
    {
        // do some code

        if ($condtion) {
          // wait for some given time and try again
        }
    }
}

据我了解,$tries = 2将处理该作业 2次,然后如果发现错误,它将失败。

问:如何在此作业的流程之间增加延迟?这样,如果满足条件,它将等待进入第二次尝试?

2 个答案:

答案 0 :(得分:1)

sleep选项将延迟工作进程之间的时间。

  

当队列中有可用的作业时,工作人员将继续处理作业,而在它们之间没有任何延迟。但是,睡眠选项确定如果没有新的工作可用,工作人员将“睡眠”多长时间(以秒为单位)。在睡眠期间,该工作人员将不会处理任何新的作业-这些工作将在该工作人员再次唤醒后进行处理。

如果您正在运行Redis,则有block_for选项将延迟对Redis数据库的轮询。

  

使用Redis队列时,您可以使用block_for配置选项来指定驱动程序在遍历worker循环并重新轮询Redis数据库之前应等待作业可用的时间。

最后,要延迟线程执行,请使用usleep

public function handle()
{
    // do some code

    if ($condtion) {
      usleep(50000); // sleep for half a second.
    }
}

答案 1 :(得分:0)

我能想到的唯一可靠的解决方案是使用$tries = 1并在条件匹配时再次分派相同的作业-但作为延迟的作业(或首先将其延迟):

DeleteInstagramImage::dispatch($this->image)
    ->delay(now()->addMinutes(1));

但是请注意,这基本上是一个无休止的循环,您还需要退出策略。例如,您可以将执行计数器存储在缓存中,该计数器在30分钟后将被删除。像Cache::put("instagram-img-deletion-{$this->image->id}", $tries, now()->addMinutes(30))这样的东西,需要事先检查尝试。