Permalink
Browse files

Added #enqueue hook

  • Loading branch information...
1 parent 0af736e commit 3e8a196cb3a8f6baf4c455361da8bf8c76bcc4b4 @bkeepers bkeepers committed Sep 9, 2010
Showing with 30 additions and 19 deletions.
  1. +14 −10 README.textile
  2. +3 −1 lib/delayed/backend/base.rb
  3. +4 −3 lib/delayed/backend/shared_spec.rb
  4. +9 −5 spec/sample_jobs.rb
View
@@ -1,6 +1,6 @@
h1. Delayed::Job
-Delated_job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background.
+Delated_job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background.
It is a direct extraction from Shopify where the job table is responsible for a multitude of core tasks. Amongst those tasks are:
@@ -9,8 +9,8 @@ It is a direct extraction from Shopify where the job table is responsible for a
* http downloads
* updating smart collections
* updating solr, our search server, after product changes
-* batch imports
-* spam checks
+* batch imports
+* spam checks
h2. Installation
@@ -92,19 +92,19 @@ $ RAILS_ENV=production script/delayed_job stop
Workers can be running on any computer, as long as they have access to the database and their clock is in sync. Keep in mind that each worker will check the database at least every 5 seconds.
-You can also invoke @rake jobs:work@ which will start working off jobs. You can cancel the rake task with @CTRL-C@.
+You can also invoke @rake jobs:work@ which will start working off jobs. You can cancel the rake task with @CTRL-C@.
h2. Custom Jobs
-Jobs are simple ruby objects with a method called perform. Any object which responds to perform can be stuffed into the jobs table. Job objects are serialized to yaml so that they can later be resurrected by the job runner.
+Jobs are simple ruby objects with a method called perform. Any object which responds to perform can be stuffed into the jobs table. Job objects are serialized to yaml so that they can later be resurrected by the job runner.
<pre>
class NewsletterJob < Struct.new(:text, :emails)
def perform
emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }
- end
-end
-
+ end
+end
+
Delayed::Job.enqueue NewsletterJob.new('lorem ipsum...', Customers.find(:all).collect(&:email))
</pre>
@@ -114,6 +114,10 @@ You can define hooks on your job that will be called at different stages in the
<pre>
class ParanoidNewsletterJob < NewsletterJob
+ def enqueue(job)
+ record_stat 'newsletter_job/enqueue'
+ end
+
def perform
emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }
end
@@ -137,12 +141,12 @@ class ParanoidNewsletterJob < NewsletterJob
def failure
page_sysadmin_in_the_middle_of_the_night
end
-end
+end
</pre>
h2. Gory Details
-The library evolves around a delayed_jobs table which looks as follows:
+The library evolves around a delayed_jobs table which looks as follows:
<pre>
create_table :delayed_jobs, :force => true do |table|
@@ -18,7 +18,9 @@ def enqueue(*args)
priority = args.first || Delayed::Worker.default_priority
run_at = args[1]
- self.create(:payload_object => object, :priority => priority.to_i, :run_at => run_at)
+ self.create(:payload_object => object, :priority => priority.to_i, :run_at => run_at).tap do |job|
+ job.hook(:enqueue)
+ end
end
# Hook method that is called before a new worker is forked
@@ -62,23 +62,24 @@ def create_job(opts = {})
it "should call before and after callbacks" do
job = described_class.enqueue(CallbackJob.new)
+ CallbackJob.messages.should == ["enqueue"]
job.invoke_job
- CallbackJob.messages.should == ["before", "perform", "success", "after"]
+ CallbackJob.messages.should == ["enqueue", "before", "perform", "success", "after"]
end
it "should call the after callback with an error" do
job = described_class.enqueue(CallbackJob.new)
job.payload_object.should_receive(:perform).and_raise(RuntimeError.new("fail"))
lambda { job.invoke_job }.should raise_error
- CallbackJob.messages.should == ["before", "error: RuntimeError", "after"]
+ CallbackJob.messages.should == ["enqueue", "before", "error: RuntimeError", "after"]
end
it "should call error when before raises an error" do
job = described_class.enqueue(CallbackJob.new)
job.payload_object.should_receive(:before).and_raise(RuntimeError.new("fail"))
lambda { job.invoke_job }.should raise_error(RuntimeError)
- CallbackJob.messages.should == ["error: RuntimeError", "after"]
+ CallbackJob.messages.should == ["enqueue", "error: RuntimeError", "after"]
end
end
View
@@ -12,7 +12,7 @@ def perform; @@runs += 1; end
class ErrorJob
cattr_accessor :runs; self.runs = 0
def perform; raise 'did not work'; end
-end
+end
class LongRunningJob
def perform; sleep 250; end
@@ -26,25 +26,29 @@ def failure
module M
class ModuleJob
cattr_accessor :runs; self.runs = 0
- def perform; @@runs += 1; end
+ def perform; @@runs += 1; end
end
end
class CallbackJob
cattr_accessor :messages
+ def enqueue(job)
+ self.class.messages << 'enqueue'
+ end
+
def before(job)
self.class.messages << 'before'
end
-
+
def perform
self.class.messages << 'perform'
end
-
+
def after(job)
self.class.messages << 'after'
end
-
+
def success(job)
self.class.messages << 'success'
end

0 comments on commit 3e8a196

Please sign in to comment.