Skip to content
Scheduler
Scheduler
Планирование отложенных заданий в MODX 2 и MODX 3
  • MODX 2
  • MODX 3
  1. Компоненты
  2. Scheduler
  3. Разработка заданий

Разработка заданий ​

Код задания — обычный PHP-файл, сниппет или процессор. Что доступно внутри каждого типа — в Создании задания.

Передача данных ​

Данные из второго аргумента schedule() попадают в задание переменной $scriptProperties. Читайте их через getOption() — он подставит значение по умолчанию, если ключа нет:

php
$clientId = $modx->getOption('client', $scriptProperties, 0);

У сниппета в $scriptProperties лежат ещё task и run — объекты задания и запуска. У процессора они достаются через $this->getProperty('task') и $this->getProperty('run').

Возврат результата ​

Верните из задания строку — она сохранится в поле message запуска и будет видна в админке. Если нужно сохранить структуру, верните JSON:

php
return json_encode(['processed' => $count], JSON_UNESCAPED_UNICODE);

echo и print не перехватываются: напечатанное уйдёт в вывод cron, а не в запуск, так что для отчёта о работе они не годятся. Увидеть результат можно в админке, на вкладке «Прошедшие запуски».

У процессорного задания результат собирается иначе: в message попадает сообщение из ответа процессора, а возвращать строку самому не нужно.

Ошибки ​

Запуск считается упавшим, если в нём есть хотя бы одна запись об ошибке. Добавляет её addError(): первый аргумент — тип ошибки, второй — массив подробностей. Возврат false на статус не влияет. У процессорного задания своя дорога: в запуск переносятся ошибки полей из ответа процессора, по одной записи на поле.

php
if (empty($scriptProperties['client'])) {
    $run->addError('missing_client', [
        'data' => $scriptProperties,
    ]);

    return 'Не передан идентификатор клиента';
}

Исключения перехватывает сам Scheduler. Непойманный Exception или Error даёт запуску ошибку с типом по имени класса исключения, а в подробностях — ключи exception (сообщение), code, file, line и trace. Проход cron при этом не прерывается и берётся за следующий запуск. Оборачивать всё задание в try/catch незачем — только если хотите обработать сбой по-своему.

А вот обрыв процесса планировщик не отслеживает: если задание убил таймаут PHP, нехватка памяти или exit, запуск так и останется в статусе «Выполняется» — он не выполнится и не упадёт. Автоматического сброса таких запусков нет, в админке их видно по счётчику «Выполняется».

Статусы и поля запуска ​

У запуска четыре статуса:

Текущий лежит в поле status, числом:

СтатусКонстантаЗначениеКогда
ЗапланированоsTaskRun::STATUS_SCHEDULED0Запуск поставлен в очередь и ждёт своего времени
ВыполняетсяsTaskRun::STATUS_EXECUTING1Проход cron забрал запуск
УспешноsTaskRun::STATUS_SUCCESS2Задание отработало и не добавило ни одной ошибки
ОшибкаsTaskRun::STATUS_FAILURE3В запуске есть запись об ошибке

Что ещё лежит в запуске:

ПолеСодержимое
taskИдентификатор задания, которому принадлежит запуск
timingКогда выполнять — метка времени из первого аргумента schedule(), округлённая до минуты
dataМассив, переданный в schedule() — он же $scriptProperties
messageЗначение, которое вернуло задание. Не строку приведёт к строке, ничего не вернули — останется пустым
errorsМассив записей об ошибках. В каждой — type, timestamp и переданные подробности, разложенные рядом с ними, а не вложенные
executedonМетка времени выполнения. У запуска, который ещё не выполнялся, пусто
processing_timeДлительность в секундах
retry_countНомер повторной попытки, 0 — первый запуск
task_keyМетка из третьего аргумента schedule()

Чтение результата из кода ​

У задания нет метода, который отдаёт последний запуск, — запуски читаются запросом. В примере $task — объект задания: внутри самого задания он уже есть, а извне его берут через getTask(), как в Планировании задания.

php
$c = $modx->newQuery('sTaskRun');
$c->where(['task' => $task->get('id')]);
$c->sortby('executedon', 'DESC');
$c->limit(1);

/** @var sTaskRun|null $lastRun */
$lastRun = $modx->getObject('sTaskRun', $c);

if ($lastRun && $lastRun->hasErrors()) {
    print_r($lastRun->get('errors'));
}