Laravel Планировщик и Cron - как Laravel знает, что не нужно запускать запланированные задания на основе daily (), ежечасно () и т.д. - PullRequest
0 голосов
/ 26 мая 2020

В Laravel в моем ядре у меня есть:

protected $commands = [
    Commands\SendRenewEmails::class,
];

/**
 * Define the application's command schedule.
 *
 * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
 * @return void
 */
protected function schedule(Schedule $schedule)
{
    // $schedule->command('inspire')
    //          ->hourly();
    $schedule->command('renew:emails')
        ->daily();
}

Указанная функция renew:emails работает как задумано, если я запускаю ее вручную через Artisan.

И в мой crontab у меня:

* */8 * * * cd /path-to-my-project && php artisan schedule:run >> /dev/null 2>&1

У меня это должно запускаться каждый 8-й час, а не каждую минуту в * * * * *, так как это живо для тестирования и просто для того, чтобы задача не запускалась каждую минуту .

Итак, как Laravel знает, когда запускать ежедневное задание на ядре и когда это происходит?

Из этой настройки (которая, кажется, быть базовой c настройкой для cronjobs в Laravel, но запускаться каждую минуту вместо каждого 8-го часа), нет журналов (которые я вижу) и таблицы в БД, чтобы отслеживать это.

Итак, если я установил для своего cron значение * * * * *, как Laravel знает не , чтобы запускать запланированное задание каждую минуту, просто потому, что я поставил ->daily(); в конце задание?

А когда у меня daily();, в какое конкретно c время это? И в спецификациях c сколько времени hourly();?

TL; DR: Как Laravel знает, что нельзя запускать те же задания снова, если он не предполагается, например, с правилом daily();? Где хранится эта информация? Как я могу быть уверен, что задание с правилом daily(); не будет запускаться каждую минуту, если мои cronjobs std:out s php artisan schedule:run каждую минуту?

1 Ответ

1 голос
/ 28 мая 2020

Под капотом Laravel планировщик использует https://github.com/dragonmantank/cron-expression, чтобы определить, запланировано ли выполнение команды или задания в данную минуту, вызывается schedule:run.

Каждая запланированная задача преобразуется в выражение cron , которое затем передается в пакет. Затем для этого выражения запускается метод с именем isDue, чтобы определить, следует ли его запускать. Итак, если вы установите задачу для запуска hourly, тогда isDue вернет true в начале часа, а Laravel будет выполняться для задачи в цикле cron.

Таким образом, информацию не нужно нигде хранить, поскольку определение выполняется на лету.

Это также может заставить вас задуматься, что может произойти, если у вас есть длительная задача, которая может занять больше времени, чем интервал. Здесь на картинке появляется withoutOverlapping. При вызове он создает так называемый мьютекс, который похож на своего рода «блокировку» (см. Что такое мьютекс? для получения дополнительной информации) при первоначальном запуске задачи. Если мьютекс уже существует для конкретной задачи в последующих циклах, это означает, что задача в настоящее время выполняется в другом цикле и не должна запускаться снова в этом.

Где хранятся мьютексы? Просто: Laravel сохраняет их в кеше, и когда мьютексная задача завершается, мьютекс удаляется из кеша. Итак, цикл продолжается.

Я мог бы go более подробно рассказать здесь, но я думаю, что это по большей части отвечает на ваш вопрос.

...