Laravel如何知道调度程序何时更新?

时间:2016-03-18 20:04:28

标签: php laravel laravel-4 laravel-5 scheduler

我的问题更多的是一般的疑惑。我使用Laravel创建了两个命令,让我们将它们称为A和B.

使用 - > dailyAt($ par)方法安排这些命令中的每一个。但$ par参数来自查询。

我的意思是这样的:

protected function schedule(Schedule $schedule)
{
    $schedulerTime_commandA = App\Model\CommandsTime::where('id', 1)->first()->time;
    $schedulerTime_commandB = App\Model\CommandsTime::where('id', 2)->first()->time;

    $schedule->command('A')
            ->dailyAt($schedulerTime_commandA);

    $schedule->command('B')
            ->dailyAt($schedulerTime_commandB);
}

这是因为超级用户想要安排这些命令运行的时间。我的问题是:Laravel如何知道App \ Console \ Kernel.php文件中的此调度方法是否已更改?

注意:我有以下cron条目,因为Laravel在文档中讨论了它。

* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1

1 个答案:

答案 0 :(得分:7)

Laravel的调度程序系统的工作方式是它使用每分钟运行一次的cron作业(这是cron条目中的* * * * *部分:匹配每个小时的每一分钟每年的每个月的一天)。

所以每分钟,php /path/to/artisan schedule:run >> /dev/null 2>&1都由cron运行。

当该命令运行时,它应检查运行时内核类schedule()方法定义的调度。

从技术上讲,Laravel本身并不知道时间表已经改变了。应该运行的每一分钟,点击schedule()方法,该方法将从数据库中获取最新值,然后返回在特定时间点设置的计划

cron的每个单独运行都不知道它之前的那些,或者它之后的那些。

至少我对调度程序的理解。我只花了一点时间在核心的Laravel内核代码中,但我相信我自己的经历会发生什么。

希望有所帮助!

修改1

刚刚在Laravel的代码中证实了我的逻辑。每次运行cron脚本时,都会重建计划,因此下次运行cron条目时将使用数据库中计划的更改。 Laravel并不真正知道它发生了变化 - 它只是在每次运行时检查并使用它发现的内容。

具体来说,如果您感兴趣,可以通过代码链接:

  1. 在命令行上调用php artisan将在项目根目录中运行artisan文件;
  2. 在工匠文件中,应用程序已引导并初始化了Kernel对象;
  3. 初始化内核类时,内核类(Laravel \ Lumen \ Console \ Kernel)的构造函数会调用defineConsoleSchedule()方法;
  4. defineConsoleSchedule()方法初始化一个空白的Schedule对象(Illuminate \ Console \ Scheduling \ Schedule);
  5. 空白的Schedule对象将被传递给Kernel类上的schedule()方法;最后
  6. 在您定义命令调度的schedule()方法中,将运行两个数据库查询,并使用数据库当时返回的值定义两个调度项。
  7. 每次控制台应用程序引导时都会发生上述操作,这意味着每次调用php artisan时,无论您希望运行什么命令。

    特别是在运行schedule:run命令时,接下来会发生什么:

    1. 应用程序引导后,初始化ScheduleRunCommand对象(Illuminate \ Console \ Scheduling \ ScheduleRuneCommand);和
    2. 在ScheduleRunCommand对象上调用fire()方法,该对象在应用程序引导时运行在Schedule对象上定义的所有命令;和
    3. 通过调用代表命令的事件(Illuminate \ Console \ Scheduling \ Event)上的isDue()方法,检查每个命令以查看当时是否必须运行该命令;最后
    4. 将运行从true返回isDue()的那一分钟需要运行的每个命令。