Периодические задачи в Ruby On Rails
Достаточно часто в веб-приложениях на Rails требуется выполнять периодические задачи. В частности, наиболее распространенной такой задачей является удаление устаревших сессий. Другими могут быть какие-либо задачи обновления данных и т.п.
Есть несколько подходов для реализации таких задач, наверное, одним из наиболее удобных является использование плагина BackgrounDrb, значительно упрощающего реализацию.
Здесь я кратко опишу процесс установки и конфигурирования плагина для выполнения какой-либо периодической задачи.
Установка BackgrounDrb
Сначала необходимо установить требуемые гемы:
sudo gem install chronic packet # Устанавливаем требуемые гемы
script/plugin install http://svn.devjavu.com/backgroundrb/trunk # Устанавливаем плагин
rake backgroundrb:setup # Конфигурирем плагин
Конфигурация
Конфигурирование осуществляется путем редактирования файла config/backgroundrb.yaml. Изначально, после установки он может выглядеть:
:backgroundrb:
:port: 11006
:ip: 0.0.0.0
В раздел :backgroundrb: можно добавлять различные опции, наиболее важными из которых являются:
- environment - какую среду Rails загружать (environment, test, production)
- port - порт, котрый будет слушать демон
- ip - адрес хоста, на котором будет работать демон
Создание периодической задачи
Для создания новой периодической задачи необходимо выполнить несколько шагов:-
Сгенерировать обработчик, вызвав:
В результате в директорию lib/workers будет добавлен новый класс MyWorker:script/generate worker my_workerclass MyWorker < BackgrounDRb::MetaWorker set_worker_name :my_worker def create(args = nil) # this method is called, when worker is loaded for the first time end end - Опеределить в MyWorker метод, который будет выполнять задачу, например do_something
-
В файле конфигурации добавить раздел :schedules:, и в него следующий код:
В :trigger_args: задается условие периодичности в виде cron-строки, в частности вышеприведенная запись означает: каждые 30 минут вызывать метод do_something объекта MyWorker. В качестве альтернативы, можно задать периодичность в виде::my_worker: :do_something: :trigger_args: * */30 * * * *
В результате весь файл config/backgroundrb.yml будет выглядеть приблизительно так::trigger_args: :start: <%= Time.now + 5.seconds %> :end: <%= Time.now + 10.minutes %> :repeat_interval: <%= 1.minute %>:backgroundrb: :port: 11006 :ip: 0.0.0.0 :environment: production :schedules: :my_worker: :do_something: :trigger_args: * */30 * * * *
