Cronのスケジュール記法を解決する
Rails + BackgrounDRb 環境で、柔軟なスケジューリングをしたくて、Cron の記法を簡単に解決できないかなぁ、とBackgrounDRbのソースを読んでいたら、CronTrigger という便利なクラスがありました。
これを使えば Rails アプリから柔軟にスケジュールを制御できていい感じ。
# cron_test.rb require 'vendor/plugins/backgroundrb/server/lib/cron_trigger' cron = BackgrounDRb::CronTrigger.new("*/10 * 8-20 * * * *") p cron.sec # 秒 p cron.min # 分 p cron.hour # 時
$ ruby cron_test.rb
[0, 10, 20, 30, 40, 50]
0..59
[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
それぞれ秒、分、時間が配列で返るようです。
BackgrounDRb は cron と違って秒と年が追加されているので注意。
これを使って、
class CreateSchedules < ActiveRecord::Migration def self.up create_table :schedules do |t| t.column :cron, :string # スケジュール t.column :task_id, :integer # タスクを表すテーブルへの外部キーのイメージ t.timestamps end end def self.down drop_table :schedules end end
のようにテーブルを作成して、カラムcronにスケジュールを入れるようにします。
class Schedule < ActiveRecord::Base def self.find_triggered(time = Time.now) find(:all).select do |sched| cron = BackgrounDRb::CronTrigger.new(sched.cron) cron.sec.include?(time.sec) and cron.min.include?(time.min) and cron.hour.include?(time.hour) end end end
のようにしておけば、Schedule.find_triggered で実行すべきタスクを取得できるようになります。
(注) 秒、分、時間以外は無視しています。
とても便利なのでCronTrigger.rb だけ切り出したい。