Skip to content

Commit

Permalink
Added options to handle_asynchronously
Browse files Browse the repository at this point in the history
  • Loading branch information
David Genord II authored and bkeepers committed Sep 26, 2010
1 parent 4add3ba commit 4784f9d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
33 changes: 33 additions & 0 deletions README.textile
Expand Up @@ -84,6 +84,39 @@ device = Device.new
device.deliver
</pre>

handle_asynchronously can take as options anything you can pass to delay. In addition the values can be Proc objects allowing call time evaluation of the value. For some examples:

<pre>
class LongTasks
def send_mailer
# Some other code
end
handle_asynchronously :send_mailer, :priority => 20

def in_the_future
# Some other code
end
# 5.minutes.from_now will be evaluated when in_the_future is called
handle_asynchronously :in_the_future, :run_at => Proc.new { 5.minutes.from_now }

def self.when_to_run
2.hours.from_now
end

def call_a_class_method
# Some other code
end
handle_asynchronously :call_a_class_method, :run_at => Proc.new { when_to_run }

attr_reader :how_important

def call_an_instance_method
# Some other code
end
handle_asynchronously :call_an_instance_method, :priority => Proc.new {|i| i.how_important }
end
</pre>

h2. Running Jobs

@script/delayed_job@ can be used to manage a background process which will start working off jobs. Make sure you've run `script/generate delayed_job`.
Expand Down
14 changes: 12 additions & 2 deletions lib/delayed/message_sending.rb
Expand Up @@ -31,11 +31,21 @@ def send_at(time, method, *args)
end

module ClassMethods
def handle_asynchronously(method)
def handle_asynchronously(method, opts = {})
aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
with_method, without_method = "#{aliased_method}_with_delay#{punctuation}", "#{aliased_method}_without_delay#{punctuation}"
define_method(with_method) do |*args|
delay.__send__(without_method, *args)
curr_opts = opts.clone
curr_opts.each_key do |key|
if (val = curr_opts[key]).is_a?(Proc)
curr_opts[key] = if val.arity == 1
val.call(self)
else
val.call
end
end
end
delay(curr_opts).__send__(without_method, *args)
end
alias_method_chain method, :delay
end
Expand Down
38 changes: 38 additions & 0 deletions spec/message_sending_spec.rb
Expand Up @@ -22,6 +22,44 @@ def tell!(arg)
job.payload_object.args.should == [1]
}.should change { Delayed::Job.count }
end

describe 'with options' do
class Fable
class << self
attr_accessor :importance
end
def tell
end
handle_asynchronously :tell, :priority => Proc.new { self.importance }
end

it 'should set the priority based on the Fable importance' do
Fable.importance = 10
job = Fable.new.tell
job.priority.should == 10

Fable.importance = 20
job = Fable.new.tell
job.priority.should == 20
end

describe 'using a proc with parament' do
class Yarn
attr_accessor :importance
def spin
end
handle_asynchronously :spin, :priority => Proc.new {|y| y.importance }
end

it 'should set the priority based on the Fable importance' do
job = Yarn.new.tap {|y| y.importance = 10 }.spin
job.priority.should == 10

job = Yarn.new.tap {|y| y.importance = 20 }.spin
job.priority.should == 20
end
end
end
end

context "delay" do
Expand Down

0 comments on commit 4784f9d

Please sign in to comment.