
Создание задания
Задание описывает, что запускать, и создаётся один раз — в админке, скриптом сборки пакета или временным сниппетом. Поставить запуск в очередь можно только у существующего задания: Планирование задания.
<?php
$task = $modx->newObject('sFileTask');
$task->fromArray([
'class_key' => 'sFileTask',
'namespace' => 'my_namespace',
'reference' => 'name_of_my_task',
'content' => 'elements/tasks/name_of_my_task.php',
'description' => 'Собирает статистику за сутки',
]);
if (!$task->save()) {
return 'Не удалось сохранить задание';
}Пара «пространство имён + название» (namespace + reference) — адрес задания: по ней его находит $scheduler->getTask(), который принимает и числовой идентификатор. Уникальность пары компонент не проверяет — следите за ней сами.
Поля задания
| Поле | В форме | По умолчанию | Назначение |
|---|---|---|---|
class_key | Тип задания | sSnippetTask | Какой код запускать. В коде указывайте явно: newObject('sFileTask') задаёт только класс объекта, а поле остаётся со значением по умолчанию, и задание пойдёт искать сниппет. В форме заранее выбран sFileTask |
namespace | Пространство имен | core | Пространство имён MODX. Для файловых заданий от него же отсчитывается относительный путь |
reference | Название | Untitled Task | Вторая половина адреса задания |
content | Путь к файлу, выбор сниппета или название процессора | пусто | Что запускать. В форме это три отдельных поля, показывается нужное по выбранному типу |
description | Описание задания | пусто | Описание для списка заданий в админке |
recurring | Циклическое | выключено | Циклическое задание: после успешного запуска встаёт следующий |
interval | Интервал | пусто | Интервал цикла, строка для strtotime() — +30 minutes, +1 hour, +1 day. Обязателен при включённом recurring; в форме поле появляется только после отметки |
max_retries | Макс. повторов | 0 | Сколько раз повторить запуск после неудачи. 0 — не повторять |
retry_delay | Задержка повтора (сек) | 60 | Пауза перед повторной попыткой, в секундах |
Поле task_key в этой таблице не значится: оно принадлежит запуску, а не заданию, и в форме подписано «Признак (key)» — не перепутайте его с «Названием».
Типы заданий
Тип задаётся полем class_key; от него зависит, что лежит в content.
| Тип | В content | Что доступно внутри |
|---|---|---|
sFileTask | путь к PHP-файлу | $modx, $task, $run, $scriptProperties |
sSnippetTask | имя или ID сниппета | $scriptProperties, в нём же task и run |
sProcessorTask | имя процессора | $this->getProperty('task') и $this->getProperty('run') |
Файловое задание удобно держать в системе контроля версий, сниппет — использовать и на сайте; процессор — класс, обычный выбор для сложной логики.
Файл
Путь из content ищется по порядку, выполняется первый найденный файл:
- как абсолютный путь;
- относительно core-пути пространства имён;
- относительно корня MODX;
- относительно core MODX.
Сниппет
Если в content число, сниппет ищется по ID, иначе по имени. Сниппет выполняется без кэширования, его вывод становится результатом запуска. Не найденный сниппет — ошибка snippet_not_found, запуск падает.
Процессор
Что писать в content, зависит от стиля процессора:
- с пространством имён (
MyPackage\Processors\Tasks\Nightly) — путь не нужен, процессор находит автозагрузчик; - без него (старый стиль MODX 2,
tasks/nightly) — путь подставляет компонент. Еслиnamespaceзадания неcore, он ищет в пакете: сначалаsrc/Processors/, если такой каталог есть, иначеprocessors/. Еслиcore— в ядре:src/Revolution/Processors/в MODX 3 иmodel/modx/processors/в MODX 2. Полеnamespaceпо умолчанию как разcore, так что задание, созданное без него, пойдёт искать процессор в ядре.
Ошибки полей от процессора переносятся в запуск, результатом становится сообщение из его ответа.
Циклические задания и повторные попытки
Это независимые механизмы. recurring с interval ставит следующий запуск после успешного, а на ошибке цикл останавливается — продолжает его настройка scheduler.recurring_on_failure (Системные настройки). max_retries повторяет упавший запуск и от этой настройки не зависит. Что происходит с запуском дальше — в Планировании задания.
Цикл останавливается молча, если interval не годится: его не разбирает strtotime() либо он даёт время не в будущем (-1 day, now). В журнал ошибок попадает [Scheduler] Invalid interval '<значение>' for task '<название>', следующий запуск не планируется. Пустой interval при включённом recurring даёт предупреждение Recurring task '<название>' has no interval set.
Форма в админке такой интервал отклоняет при сохранении, так что подвести может только задание, созданное кодом.
Создание в админке
Дополнения → Планировщик → Задания → Создать задание. В форме те же поля, что в таблице выше. Разовые и служебные задания удобнее создавать здесь, задания в составе пакета — скриптом сборки.
