Как стать автором
Обновить

Медленные и/или ресурсоёмкие задачи в коде: отложенные задания, очереди, задачи с ручной обработкой

PHP *
Публикую по просьбе eugenioz.

При работе больших Web проектов бывают такие задачи, выполнение которых не является необходимым прямо сейчас, однако действия критические и выполнить их обязательно. Такие действия можно проводить прямо в коде и при неудачной попытке повторять. Но, на мой взгляд, подобное лучше сразу выполнять вне основного кода задачи: этим разгружается код и достигается однообразие выполнения.

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

В качестве средства распределения задач предлагаю вашему вниманию PHP-класс Tasks.

Код класса

И теперь пояснения.

Задачи хранятся во временной директории в виде файлов. Скрипт, запускаемый по крону, получает список задач и выполняет у каждой задачи метод execute. После успешного исполнения файл задачи удаляется. Класс можно переработать для работы с MySQL-базой. Это имеет смысл, поскольку можно делать DELAYED INSERT, который не блокирует исполнение, однако сейчас используется файловая система в силу её большей надёжности.

Создаётся задача как обычный элемент алгоритма, не изменяя логики.

Например, было:
$q_upd=update_order_data($params);
стало
$q_upd=tasks::create("update_order_data", 'api', 0, $params);

У задач есть уровень приоритета, благодаря чему можно при каждом запуске cron-скрипта выполнять задачи в порядке «важности». Чем больше параметр priority, тем дальше отложится задача.

Вариант cron-скрипта: код.

Рядом с классом Tasks в коде есть класс task_handlers — именно в task_handlers вы можете создать обработчик.
Имя функции этого класса является именем обработчика, которое можно задать в момент создания задачи. В качестве примера приведены обработчики 'mysql' и 'mail' — их код мал, поэтому удобен для иллюстрации.

Автор кода — eugenioz, разрешает использовать код под лицензией MIT.

Несмотря на простоту и легковесность этого класса, он позволяет очень эффективно распределить нагрузку, не изменяя при этом логику алгоритмов.

Ещё раз примеры применения:
  • на странице настройки профиля одного из сервисов нужно взаимодействовать с другим сайтом, подтверждая у него данные. Сайт этот тоже мог ответить «не сразу». Вывод лаконичного «проверяется» в одном из блоков — гораздо лучше, чем генерация всей страницы в несколько секунд из-за задержки в одной строке;
  • в данный момент для всех посетителей, которые зашли на wap-сайт с мобильного телефона, и чей IP не оказался в списке IP-гейтов операторов, создаётся задача проверки IP. В свободное время берётся whois-информация об IP и проверяется на наличие слов, которые могут указывать на принадлежность к оператору сотовой связи. При наличии таких слов IP добавляется в список «на проверку» и после «ручной» проверки этот IP может быть внесён в список IP-гейтов операторов;
  • работа с удалённым API, который может быть недоступен, но действие может быть отложено и должно быть исполнено. Например, зачастую реселлерские панели не повторяют заказов, что приводит к большому количеству жалоб и упущенной выгоде.


eugenioz: Внимательно выслушаю конструктивную критику, вопросы и предложения по улучшению.
Теги:
Хабы:
Всего голосов 30: ↑17 и ↓13 +4
Просмотры 4K
Комментарии Комментарии 96