From 5042244f486b8ee976926f4b4007de182718f0ef Mon Sep 17 00:00:00 2001 From: humancopy Date: Tue, 20 Sep 2011 20:10:46 +0200 Subject: [PATCH] Add before & after dequeue hooks. --- lib/resque.rb | 10 +++++++ lib/resque/plugin.rb | 10 +++++++ test/job_hooks_test.rb | 62 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/lib/resque.rb b/lib/resque.rb index a3ec9416b..b2cc11955 100644 --- a/lib/resque.rb +++ b/lib/resque.rb @@ -265,7 +265,17 @@ def enqueue(klass, *args) # # This method is considered part of the `stable` API. def dequeue(klass, *args) + # Perform before_dequeue hooks. Don't perform dequeue if any hook returns false + before_hooks = Plugin.before_dequeue_hooks(klass).collect do |hook| + klass.send(hook, *args) + end + return if before_hooks.any? { |result| result == false } + Job.destroy(queue_from_class(klass), klass, *args) + + Plugin.after_dequeue_hooks(klass).each do |hook| + klass.send(hook, *args) + end end # Given a class, try to extrapolate an appropriate queue based on a diff --git a/lib/resque/plugin.rb b/lib/resque/plugin.rb index 5f9c598c5..41cc6a46a 100644 --- a/lib/resque/plugin.rb +++ b/lib/resque/plugin.rb @@ -52,5 +52,15 @@ def after_enqueue_hooks(job) def before_enqueue_hooks(job) job.methods.grep(/^before_enqueue/).sort end + + # Given an object, returns a list `after_dequeue` hook names. + def after_dequeue_hooks(job) + job.methods.grep(/^after_dequeue/).sort + end + + # Given an object, returns a list `before_dequeue` hook names. + def before_dequeue_hooks(job) + job.methods.grep(/^before_dequeue/).sort + end end end diff --git a/test/job_hooks_test.rb b/test/job_hooks_test.rb index 356ee32a2..5b800629d 100644 --- a/test/job_hooks_test.rb +++ b/test/job_hooks_test.rb @@ -290,6 +290,68 @@ def self.perform(history) end end +context "Resque::Job after_dequeue" do + include PerformJob + + class ::AfterDequeueJob + @queue = :jobs + def self.after_dequeue_record_history(history) + history << :after_dequeue + end + + def self.perform(history) + end + end + + test "the after dequeue hook should run" do + history = [] + @worker = Resque::Worker.new(:jobs) + Resque.dequeue(AfterDequeueJob, history) + @worker.work(0) + assert_equal history, [:after_dequeue], "after_dequeue was not run" + end +end + + +context "Resque::Job before_dequeue" do + include PerformJob + + class ::BeforeDequeueJob + @queue = :jobs + def self.before_dequeue_record_history(history) + history << :before_dequeue + end + + def self.perform(history) + end + end + + class ::BeforeDequeueJobAbort + @queue = :jobs + def self.before_dequeue_abort(history) + false + end + + def self.perform(history) + end + end + + test "the before dequeue hook should run" do + history = [] + @worker = Resque::Worker.new(:jobs) + Resque.dequeue(BeforeDequeueJob, history) + @worker.work(0) + assert_equal history, [:before_dequeue], "before_dequeue was not run" + end + + test "a before dequeue hook that returns false should prevent the job from getting queued" do + history = [] + @worker = Resque::Worker.new(:jobs) + Resque.dequeue(BeforeDequeueJobAbort, history) + assert_equal 0, Resque.size(:jobs) + end +end + context "Resque::Job all hooks" do include PerformJob