Планировщик задач cron

SKY / WINGS / SECOND /
CRON1
Задачи `cron` обычно находятся в `main/cron.php`, файл запускается раз в минуту, но время выполнения каждой задачи указывается непосредственно перед лямбда-функцией с помощью обычного cron-синтаксиса. Задачи выполняются в отдельных потоках, возможно параллельно несколько сразу (обеспечивается с помощью функции PHP `popen(..)`), поэтому даже фатальные ошибки отдельной задачи не нарушают работу остальных задач и регистрируются в системе регистрации ошибок. Функционал реализован в классе `Schedule` см. файл `main/w2/schedule.php`. Пример файла cron.php:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
<?php 'cli' == PHP_SAPI or exit;
 
$argv[0] = __FILE__# correct a value with a full path
chdir(realpath(__DIR__ '/..'));
require 'main/w2/emit.php';
$cron
 
->at('0 2', function() use ($cron) {
    $cron->sql('delete from visitors
        where (dt_l + interval $. day < now()) and uid is null'$cron->n_clear_nc);
})
 
# .. other tasks
 
->at('3 3', function() {
    require 'main/c_sitemap.php';
})
->at('15 6', function() use ($cron) {
    $cron->mail_error();
})
 
;#!
 


В задачах вместо глобальной функции sql(), можно использовать Schedule::sql(), используя тот-же синтаксис, но вторая еще и логирует свое исполнение в cron-логе, например:

2018-05-01 00:02:01 [0] 0.001 sec <= 2423 <= delete from visitors where ...

Также для логирования, чтобы записать произвольную строку, можно использовать метод Schedule::write()

С помощью функции Schedule::mail_error() можно организовать задачу отсылки письма, если на продакшн, появились новые ошибки и они не просмотрены в логе ошибок.

В классе реализовано также две "магические задачи", они выполняются всегда: вычисление текущего количества пользователей "online", и автоматический перевод на зимнее-летнее время установок для MySQL.

Если запустить файл без параметров, т.е. `php cron.php`, весь вывод, в том числе фатальные ошибки, будут выдаваться в STDOUT, к вам в консоль. В системном планировщике CRON, файл следует запускать с параметром @. Например: `php cron.php @`, в этом случае в STDOUT не будет выдаваться ничего, даже фатальные ошибки задач, но весь вывод будет записываться в лог ошибок `memory.4` или лог cron `memory.2`.

Если запускаете файл cron.php "руками", можно поставить плюс или минус перед расписанием выполнения задачи:

001
002
003
004
005
006
007
008
<?php
->at('+3 3', function() {
    require 'main/c_sitemap.php';
})
->at('-15 6', function() use ($cron) {
    $cron->mail_error();
})
 

Плюс обеспечит запуск задачи "всегда", а минус "никогда". Это удобно использовать в отладочных целях, не затерая расписание, управлять выполнением задачи по необходимости.

Если функция popen() запрещена по соображениям безопасности, задачи будут выполняться в одном процессе. Вам нужно позаботиться о том, чтобы времена выполнения задач не пересекались. Иначе фатальные ошибки одной задачи, могут не дать возможности выполниться последующей задаче. Если боитесь ошибиться, следует отказаться от использования класса и каждую задачу запускать отдельно в системном планировщике cron. Вы должны помнить, что если вы отказались от использования класса Schedule, его "магические задачи" не будут выполняться и их, вероятно, нужно будет организовать самостоятельно либо все же запустить одну cron-задачу с использованием класса.
опубликовано ENERGY - 4 Jun 2018 03:39 GMT
последнее редактирование - 27 Jun 2018 05:12 GMT
 +  0  -  комментировать