diff --git a/README.markdown b/README.markdown index 5acd4b2c..f0c23250 100644 --- a/README.markdown +++ b/README.markdown @@ -158,10 +158,15 @@ The schedule is a list of Resque worker classes with arguments and a schedule frequency (in crontab syntax). The schedule is just a hash, but is most likely stored in a YAML like so: + CancelAbandonedOrders: + cron: "*/5 * * * *" + queue_documents_for_indexing: cron: "0 0 * * *" # you can use rufus-scheduler "every" syntax in place of cron if you prefer # every: 1hr + # By default the job name (hash key) will be taken as worker class name. + # If you want to have a different job name and class name, provide the 'class' option class: QueueDocuments queue: high args: diff --git a/lib/resque_scheduler.rb b/lib/resque_scheduler.rb index 043a6562..bd89abad 100644 --- a/lib/resque_scheduler.rb +++ b/lib/resque_scheduler.rb @@ -10,21 +10,29 @@ module ResqueScheduler # # Accepts a new schedule configuration of the form: # - # {'some_name' => {"cron" => "5/* * * *", - # "class" => "DoSomeWork", - # "args" => "work on this string", - # "description" => "this thing works it"s butter off"}, - # ...} + # { + # "MakeTea" => { + # "every" => "1m" }, + # "some_name" => { + # "cron" => "5/* * * *", + # "class" => "DoSomeWork", + # "args" => "work on this string", + # "description" => "this thing works it"s butter off" }, + # ... + # } # - # 'some_name' can be anything and is used only to describe and reference - # the scheduled job + # Hash keys can be anything and are used to describe and reference + # the scheduled job. If the "class" argument is missing, the key + # is used implicitly as "class" argument - in the "MakeTea" example, + # "MakeTea" is used both as job name and resque worker class. # - # :cron can be any cron scheduling string :job can be any resque job class + # :cron can be any cron scheduling string # # :every can be used in lieu of :cron. see rufus-scheduler's 'every' usage # for valid syntax. If :cron is present it will take precedence over :every. # - # :class must be a resque worker class + # :class must be a resque worker class. If it is missing, the job name (hash key) + # will be used as :class. # # :args can be any yaml which will be converted to a ruby literal and # passed in a params. (optional) @@ -36,6 +44,8 @@ module ResqueScheduler # params is an array, each element in the array is passed as a separate # param, otherwise params is passed in as the only parameter to perform. def schedule=(schedule_hash) + schedule_hash = prepare_schedule(schedule_hash) + if Resque::Scheduler.dynamic schedule_hash.each do |name, job_spec| set_schedule(name, job_spec) @@ -272,6 +282,16 @@ def after_schedule_hooks(klass) klass.methods.grep(/^after_schedule/).sort end + def prepare_schedule(schedule_hash) + prepared_hash = {} + schedule_hash.each do |name, job_spec| + job_spec = job_spec.dup + job_spec['class'] = name unless job_spec.key?('class') || job_spec.key?(:class) + prepared_hash[name] = job_spec + end + prepared_hash + end + end Resque.extend ResqueScheduler diff --git a/test/scheduler_test.rb b/test/scheduler_test.rb index aa6d0036..88bbf853 100644 --- a/test/scheduler_test.rb +++ b/test/scheduler_test.rb @@ -165,6 +165,24 @@ Resque.decode(Resque.redis.hget(:schedules, "my_ivar_job"))) end + test "schedule= uses job name as 'class' argument if it's missing" do + Resque::Scheduler.dynamic = true + Resque.schedule = {"SomeIvarJob" => { + 'cron' => "* * * * *", 'args' => "/tmp/75" + }} + assert_equal({'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/75"}, + Resque.decode(Resque.redis.hget(:schedules, "SomeIvarJob"))) + assert_equal('SomeIvarJob', Resque.schedule['SomeIvarJob']['class']) + end + + test "schedule= does not mutate argument" do + schedule = {"SomeIvarJob" => { + 'cron' => "* * * * *", 'args' => "/tmp/75" + }} + Resque.schedule = schedule + assert !schedule['SomeIvarJob'].key?('class') + end + test "set_schedule can set an individual schedule" do Resque.set_schedule("some_ivar_job", { 'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/22"