Отложенное исполнение

Материал из Eludia
Перейти к: навигация, поиск

Содержание

Eludia содержит механизм, позволяющий откладывать исполнение некоторых вызовов функций (в частности, рассылку e-mail), результаты которых не используются при генерации HTTP-ответов.

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

Чтобы зарегистрировать вызов функции $sub с напором аргументов @params в очереди, нужно воспользоваться подпрограммой

defer ($sub, \@params);

Она также имеет 3-й, необязательный, параметр: набор опций.

defer ($sub, \@params, {label => $label});

Единственная доступная на нынешний момент опция label — это символическое имя задания. Оно может пригодиться для разработки WEB-интерфейса управления очередью, но пока не используется.

Первое применение функции defer — отсрочка рассылки e-mail. Поэтому она интегрирована в функцию send_mail: для того, чтобы при её вызове письма откладывались в очередь, достаточно прописать

defer => 1

в $preconf -> {mail};

Обслуживание очереди

Настройка

Для того, чтобы отложенные вызовы не только запоминались, но и исполнялись, необходимо отдельно позаботиться о часовом механизме. На текущий момент рассматривается единственный вариант: offline-скрипт, запускаемый по cron.

Скрипт должен иметь вид:

#!/usr/bin/perl -w
no warnings;

package MY_APPLICATION;
use Eludia::Offline;

check_deferred ({ 
 cnt     => 10,
 pidfile => $preconf -> {deferred_pidfile},
});

Как нетрудно видеть, собственно очередь обслуживает функция check_deferred. Опцию pidfile можно не задавать, тогда будет подставлено значение '/var/run/defer_MY_APPLICATION', но если pid-файл задаётся напрямую, то делать это надо обязательно с использованием $preconf.

Опция cnt определяет максимальное количество попыток вызовов, которые инициирует скрипт за 1 раз. Если скрипт будет вторично запущен в то время, как предыдущая копия ещё не отработала, то старый процесс будет прекращён, а последнее задание останется в очереди и его попытаются исполнить вновь.

Если окажется, что какое-то задание никогда не может быть исполнено до аварийного останова скрипта, это не парализует работу очереди, поскольку задания выбираются в случайном порядке.

Строка crontab для вызова скрипта check_deferred.pl раз в 2 минуты с дозаписью stderr в /var/log/deferred.log может иметь вид:

0-55/2 * * * * root perl /var/projects/my_application/lib/offline/check_deferred.pl 2>>/var/log/deferred.log

Чтобы распараллелить обслуживание очереди, следует ввести зависимость имени pid-файла от параметра командной строки скрипта и настроить несколько cron-вызовов.

Соображения эффективности

Итак, очередь параметризуется:

  • количеством строк crontab для вызова скрипта;
  • частотами запуска для каждой из этих строк;
  • количеством заданий, исполняемых за один запуск.

Все эти параметры должны подбираться для каждого сервера отдельно. Следует соблюдать простое правило, вытекающее из теории массового обслуживания: среднее количество запросов, которое можно обслужить в единицу времени, не должно быть меньше, чем среднее количество запросов, поступающих в такую же единицу времени.

Например, если почтовый сервер отправляет письмо не меньше, чем за минуту, и одновременно сервер приложения генерирует 2 почтовых нотификации в минуту, очевидно, количество заданий в очереди будет расти со скоростью 1 вызов в минуту, и задержки в отправке писем быстро сделают нотификации как таковые бессмысленными. Очередь может скомпенсировать отдельные всплески интенсивности заявок, но не ускорить их обслуживание.

Хранение данных

Задания (имена функций и параметры) хранятся в таблице __deferred. Таблица __deferred_hot, имеющая то же пространство id, что __deferred, указывает на те вызовы, которык предстоит исполнить. В таблице __deferred_log фиксируются результаты попыток исполнения запросов.

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Разработчику
Администратору
Инструменты