Перейти к содержанию

Задания и cron

Всё медленное или подверженное сбоям (отправка почты, доставка уведомлений, чтение почтового ящика, индексация для поиска) выполняется как задание в очереди, а не внутри запроса, который его вызвал. Задания запускают три механизма: встроенная обработка, догоняющая обработка и фоновый процесс в cron.

Настройка cron

Фоновый процесс — bin/plugin helpdesk-pro work. Helpdesk Pro добавляет его в планировщик Grav как helpdesk-pro-jobs каждую минуту, поэтому нужно только поместить планировщик Grav в crontab:

PATH=/usr/local/bin:/usr/bin:/bin
* * * * * cd /path/to/site && php bin/grav scheduler >> /dev/null 2>&1

Укажите в строке PATH папку, где находится ваш бинарник PHP. Например, на macOS с Homebrew это что-то вроде /opt/homebrew/opt/php@8.4/bin.

Важно

Строка PATH не является необязательной. bin/plugin начинается с #!/usr/bin/env php, а планировщик запускает его как дочерний процесс, наследующий минимальный PATH из cron. Абсолютный путь к PHP в строке crontab исправляет родительский процесс, но не дочерний, поэтому планировщик может выглядеть здоровым, а каждое задание Helpdesk Pro будет завершаться с env: php: No such file or directory. Запустите bin/grav scheduler -d, чтобы вывести ошибки каждого задания.

Каждый запуск фонового процесса:

  1. выполняет готовые задания до 50 секунд (--max-time) и до 50 заданий (--max-jobs);
  2. планирует периодические задания, у которых ничего не ждёт;
  3. записывает время запуска, чтобы рабочая область могла предупредить об остановке cron;
  4. запускает тик фонового процесса для дополнений.

Фоновый процесс отказывается работать, пока есть ожидающие миграции.

Встроенная обработка

Когда запрос ставит задания в очередь, Helpdesk Pro выполняет эти задания, и только их, сразу после отправки ответа, в пределах jobs.inline_budget_seconds (3). Поэтому письмо с ответом сотрудника уходит через пару секунд. Чей-то клик не оплачивает чужую очередь: задания, поставленные другими запросами, ждут фонового процесса.

На PHP-FPM ответ уже у браузера, когда начинается обработка, поэтому посетителю это ничего не стоит. На mod_php браузер получил страницу, но процесс PHP остаётся занят обработкой, поэтому бюджет маленький.

Установите jobs.inline_drain в false, если работа после ответа создаёт проблемы на вашем хостинге. Тогда все задания забирает cron.

Догоняющая обработка без cron

Встроенная обработка запускает только то, что поставил запрос, а письмо-уведомление никогда не готово в том запросе, который его поставил: сначала уведомление ждёт льготный период или окно пакета. На сайте без cron такие письма ждали бы, пока что-нибудь не запустит фоновый процесс.

jobs.catch_up (включена по умолчанию) закрывает этот пробел. После ответа на веб-запрос Helpdesk Pro выполняет несколько готовых заданий, кто бы их ни поставил:

  • только если cron-процесс не запускался последние две минуты, поэтому сайт с работающим cron за это не платит;
  • не чаще раза в минуту для всего сайта;
  • не более пяти заданий и двух секунд за проход;
  • никогда до появления базы данных, поэтому сайт, который никогда не пользовался поддержкой, не получит её из-за просмотра страницы.

Проход также планирует периодические задания, которые иначе запланировал бы только фоновый процесс. Страницы фронтенда и вызовы API считаются веб-запросами; CLI никогда не выполняет догоняющую обработку.

Типы заданий из jobs.catch_up_exclude никогда не выполняются проходом. По умолчанию там search.embed, потому что встраивание для семантического поиска — медленная сетевая работа, которая должна выполняться в фоновом процессе. Установите jobs.catch_up в false, чтобы отключить догоняющую обработку; отключение jobs.inline_drain также отключает её.

Примечание

Догоняющая обработка зависит от посетителей. Тихий сайт отправляет почту поздно, поэтому настройте cron. Догоняющая обработка — страховка, а не план.

Повторные попытки и сбои

Задание, выбросившее исключение, повторяется с задержкой (30 секунд, затем 60, затем 120, максимум час), до трёх попыток или собственного лимита задания. После этого оно остаётся неудачным с последней ошибкой, пока кто-нибудь не запустит его снова. Неудачные задания никогда не удаляются очисткой по срокам хранения.

bin/plugin helpdesk-pro jobs --state=failed    # список неудачных заданий с последней ошибкой
bin/plugin helpdesk-pro jobs --run=<id>        # запустить одно снова сейчас

Задание, выполняющееся дольше jobs.job_timeout_seconds (120), считается неудачным и повторяется.

Состояние фонового процесса

bin/plugin helpdesk-pro status, Operations → System и GET /helpdesk-pro/status сообщают, когда фоновый процесс запускался последний раз и как, сколько заданий ожидает или завершилось неудачно, а также stale, когда задания ждут больше десяти минут и процесс не запускался столько же. В той же ситуации рабочая область показывает предупреждающую полосу.

Периодические задания

Задание Частота Что делает
maintenance.prune Ежедневно Удаляет завершённые задания старше jobs.retention_days и выполняет всю очистку по срокам: старые окна ограничения частоты, истёкшие ссылки для входа, присутствие, отправленные письма, старые события справочного центра, старые прочитанные уведомления, старые запуски правил, старые доставки в каналы.
rules.sweep Каждые десять минут Выполняет правила по времени и встроенное автоматическое закрытие (Правила и автоматизация).
sla.scan Каждую минуту Фиксирует наступившие предупреждения и нарушения SLA и уведомляет о них (SLA). Не планируется, пока sla.enabled выключен.
imap.poll Каждые inbound.imap.interval_seconds (две минуты) Читает почтовый ящик IMAP, пока приёмник — imap (Входящая почта).
digest.sweep Ежечасно Отправляет каждому человеку ежедневный дайджест, когда наступает его час дайджеста (Уведомления).
attachments.gc Ежечасно Истекает невостребованные черновые загрузки и удаляет сохранённые файлы, на которые больше ничего не ссылается.
kb.sync Ежечасно Переиндексирует базу знаний, когда статья изменилась вне Grav (git sync, FTP, развёртывание).

Другие задания

Задание Что делает
mail.send Обрабатывает очередь почты (Исходящая почта).
notify.deliver Письмо-уведомление как запасной вариант для одного человека.
magic_link.send Отправляет ссылку для входа.
channel.deliver Отправляет одно сообщение в один канал уведомлений по своим правилам повторных попыток.
inbound.process, inbound.fetch Обрабатывает полученное письмо или загружает письмо, на которое провайдер только сослался.
search.index, search.rebuild, search.embed Индексация поиска, перестроение и семантическое встраивание (только фоновый процесс).
sla.recompute Пересчитывает сроки SLA после изменения политики или рабочих часов.
people.erase Удаляет человека.

Настройки

На вкладке Advanced настроек плагина:

Ключ По умолчанию Что делает
jobs.inline_drain true Выполнять задания, поставленные запросом, сразу после отправки ответа.
jobs.inline_budget_seconds 3 Сколько один запрос может потратить на свои задания после ответа (не более 30).
jobs.catch_up true На сайте, где cron не запускался две минуты, выполнять несколько готовых заданий после веб-запроса, не чаще раза в минуту.
jobs.catch_up_exclude [search.embed] Типы заданий, которые никогда не выполняет догоняющая обработка.
jobs.job_timeout_seconds 120 Задание, выполняющееся дольше, считается неудачным и повторяется. 0 отключает ограничение.
jobs.retention_days 30 Завершённые и отменённые задания удаляются через столько дней. Неудачные задания никогда не очищаются.