Skip to content

Commit

Permalink
Use job name as implicit class name in the schedule
Browse files Browse the repository at this point in the history
When configuring the schedule, the only required argument is 'class'.
On the other hand, the job name (hash key) is not too useful and usually
just duplicates the resque worker class name (underscored).

So instead of having to do:

    some_job:
      class: SomeJob
      cron: '* * * * *'
    another_job:
      class: AnotherJob
      every: 1m
    job_name_different_than_class:
      class: WeirdlyNamedClass

You can now do:

    SomeJob:
      cron: '* * * * *'
    AnotherJob:
      every: 1m
    job_name_different_than_class:
      class: WeirdlyNamedClass

By default, the job name will be treated as class name,
but you can still provide a different job name and class name.
  • Loading branch information
exviva committed Feb 8, 2012
1 parent cbad714 commit 84e9f32
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 9 deletions.
5 changes: 5 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
38 changes: 29 additions & 9 deletions lib/resque_scheduler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions test/scheduler_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 84e9f32

Please sign in to comment.