1

例如,我每 5 分钟解析一些 HTML 页面和 API 端点以跟踪更改。为此,我创建了 ParseJob,我在其中进行解析并将更改保存到数据库。ParseJob 实现了 ShouldQueue 接口,我已将队列驱动程序更改为 Redis。为了定期运行 ParseJob,我创建了 ParseCommand 并将其添加到调度中:

class ParseCommand extends Command
{
    protected $signature = 'application:my-parse-command';

    public function handle()
    {
        $this->dispatch(new ParseJob());
    }
}


class Kernel extends ConsoleKernel
{
    protected $commands = [
        Commands\ParseCommand::class
   ];

    protected function schedule(Schedule $schedule)
    {
           $schedule->command('application:my-parse-command')
            ->everyFiveMinutes();
    }
}

并且队列工作者作为守护进程启动以处理队列。因此,每 5 分钟 ParseJob 被推送到队列中,并且队列工作者正在处理该作业。

有时队列工作进程崩溃、冻结或由于其他原因无法正常工作。但是每 5 分钟的作业会被推送到队列中。一个小时的停机时间后,我有 12 个作业在队列中,但它们在那段时间无关紧要,因为我不需要在某个时间解析 12 次,我只想要一个解析作业。

所以我想为一个像 Redis 中的 expire 命令一样工作的作业设置 TTL。怎么做?或者,也许您有替代解决方案?

4

1 回答 1

1

据我所知,不可能在 Laravel 队列中显式设置作业过期。解决方案可能是expires_at在您的内部设置一个属性,ParseJob并在执行之前检查:

class ParseCommand extends Command
{
    protected $signature = 'application:my-parse-command';

    public function handle()
    {
        $this->dispatch(new ParseJob(Carbon::now()->addMinutes(5)));
    }
}

然后在你的工作课上

class ParseJob {

    protected $expires_at;

    public function __construct(Carbon $expires_at) {
       $this->expires_at = $expires_at;
    }

    public function handle() 
    {

        if(!Carbon::now()->gt($this->expires_at)) {
           // Parse data
        }

    }

}
于 2017-08-31T13:24:56.260 回答