Skip to content

Commit

Permalink
Rework UniqueJob as module
Browse files Browse the repository at this point in the history
In order to have flexiblity implement module Resque::Plugins::UniqueJob
instead of old class Resque::Plugins::Loner::UniqueJob remained with deprecation
warning.
  • Loading branch information
bogdan committed Mar 19, 2011
1 parent 376fb3c commit 2ada35a
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.markdown
Expand Up @@ -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:

Expand Down
4 changes: 2 additions & 2 deletions lib/resque-loner/helpers.rb
Expand Up @@ -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.
Expand Down Expand Up @@ -57,4 +57,4 @@ def self.cleanup_loners(queue)
end
end
end
end
end
39 changes: 33 additions & 6 deletions 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
end
5 changes: 4 additions & 1 deletion resque-loner.gemspec
Expand Up @@ -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)
Expand Down
20 changes: 18 additions & 2 deletions spec/loner_spec.rb
Expand Up @@ -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
Expand All @@ -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"
Expand Down

0 comments on commit 2ada35a

Please sign in to comment.