diff --git a/README.markdown b/README.markdown index 9808d58..3e4bd26 100644 --- a/README.markdown +++ b/README.markdown @@ -95,7 +95,7 @@ The last part of this key is the job's ID, which is pretty much your queue item' { 'class': 'CacheSweeper', 'args': [1] }` -The default method to create a job ID from these parameters is to do some normalization on the payload and then md5'ing it (defined in `Resque::Plugins::Loner::UniqueJob#redis_key`). +The default method to create a job ID from these parameters is to do some normalization on the payload and then md5'ing it (defined in `Resque::Plugins::UniqueJob#redis_key`). You could also use the whole payload or anything else as a redis key, as long as you make sure these requirements are met: diff --git a/lib/resque-loner/helpers.rb b/lib/resque-loner/helpers.rb index 8b92246..df64ab8 100644 --- a/lib/resque-loner/helpers.rb +++ b/lib/resque-loner/helpers.rb @@ -28,7 +28,7 @@ def self.unique_job_queue_key(queue, item) def self.item_is_a_unique_job?(item) begin klass = constantize(item[:class] || item["class"]) - klass.ancestors.include?(::Resque::Plugins::Loner::UniqueJob) + klass.included_modules.include?(::Resque::Plugins::UniqueJob) rescue false # Resque testsuite also submits strings as job classes while Resque.enqueue'ing, end # so resque-loner should not start throwing up when that happens. @@ -57,4 +57,4 @@ def self.cleanup_loners(queue) end end end -end \ No newline at end of file +end diff --git a/lib/resque-loner/unique_job.rb b/lib/resque-loner/unique_job.rb index d919c3a..634998f 100644 --- a/lib/resque-loner/unique_job.rb +++ b/lib/resque-loner/unique_job.rb @@ -1,27 +1,54 @@ require 'digest/md5' # -# If you want your job to be unique, subclass it from this class. If you wish, +# If you want your job to be unique, include this module in it. If you wish, # you can overwrite this implementation of redis_key to fit your needs # module Resque module Plugins - module Loner - class UniqueJob - extend Resque::Helpers + module UniqueJob + + def self.included(base) + base.extend ClassMethods + base.class_eval do + base.send(:extend, Resque::Helpers) + end + end # self.included + + module ClassMethods + # # Payload is what Resque stored for this job along with the job's class name. # On a Resque with no plugins installed, this is a hash containing :class and :args # - def self.redis_key(payload) + def redis_key(payload) payload = decode(encode(payload)) # This is the cycle the data goes when being enqueued/dequeued job = payload[:class] || payload["class"] args = payload[:args] || payload["args"] digest = Digest::MD5.hexdigest encode(:class => job, :args => args) digest end + end # ClassMethods + + + end + end +end +module Resque + module Plugins + module Loner + class UniqueJob + + include Resque::Plugins::UniqueJob + + def self.inherited(host) + super(host) + return if @__unique_job_warned + warn "Inherit Resque::Plugins::Loner::UniqueJob is deprecated. Include Resque::Plugins::UniqueJob module instead." + @__unique_job_warned = true + end end end end -end \ No newline at end of file +end diff --git a/resque-loner.gemspec b/resque-loner.gemspec index f31414c..e94b30a 100644 --- a/resque-loner.gemspec +++ b/resque-loner.gemspec @@ -25,7 +25,10 @@ Gem::Specification.new do |s| Makes sure that for special jobs, there can be only one job with the same workload in one queue. Example: - class CacheSweeper < Resque::Plugins::Loner::UniqueJob + class CacheSweeper + + include Resque::Plugins::UniqueJob + @queue = :cache_sweeps def self.perform(article_id) diff --git a/spec/loner_spec.rb b/spec/loner_spec.rb index 2bf4150..a85cef2 100644 --- a/spec/loner_spec.rb +++ b/spec/loner_spec.rb @@ -11,18 +11,28 @@ class SomeJob @queue = :some_queue end -class SomeUniqueJob < Resque::Plugins::Loner::UniqueJob +class SomeUniqueJob + + include Resque::Plugins::UniqueJob + @queue = :other_queue def self.perform(foo); end end -class FailingUniqueJob < Resque::Plugins::Loner::UniqueJob +class FailingUniqueJob + include Resque::Plugins::UniqueJob @queue = :other_queue def self.perform(foo) raise "I beg to differ" end end +class DeprecatedUniqueJob < Resque::Plugins::Loner::UniqueJob + + @queue = :other_queue + def self.perform(foo); end +end + describe "Resque" do before(:each) do @@ -43,6 +53,12 @@ def self.perform(foo) Resque.enqueue SomeUniqueJob, "foo" Resque.size(:other_queue).should == 1 end + + it "should support deprecated Resque::Plugins::Loner::UniqueJob class" do + Resque.enqueue DeprecatedUniqueJob, "foo" + Resque.enqueue DeprecatedUniqueJob, "foo" + Resque.size(:other_queue).should == 1 + end it "should allow the same jobs to be executed one after the other" do Resque.enqueue SomeUniqueJob, "foo"