resque-loner 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +92 -0
- data/.simplecov +1 -0
- data/.travis.yml +12 -0
- data/CHANGELOG.markdown +11 -0
- data/Gemfile +4 -5
- data/README.markdown +4 -1
- data/Rakefile +13 -41
- data/lib/resque-ext/job.rb +9 -9
- data/lib/resque-ext/resque.rb +4 -9
- data/lib/resque-loner.rb +2 -1
- data/lib/resque-loner/helpers.rb +22 -9
- data/lib/resque-loner/legacy_helpers.rb +91 -0
- data/lib/resque-loner/unique_job.rb +23 -14
- data/lib/resque-loner/version.rb +1 -1
- data/resque-loner.gemspec +41 -32
- data/spec/loner_spec.rb +73 -51
- data/spec/spec_helper.rb +19 -3
- data/spec/support/redis_instance.rb +133 -0
- data/test/airbrake_test.rb +27 -0
- data/test/dump.rdb +0 -0
- data/test/job_hooks_test.rb +191 -52
- data/test/job_plugins_test.rb +33 -31
- data/test/plugin_test.rb +38 -26
- data/{spec/redis-test.conf → test/redis-test-cluster.conf} +4 -4
- data/test/resque-web_test.rb +23 -17
- data/test/resque_failure_redis_test.rb +23 -0
- data/test/resque_test.rb +56 -37
- data/test/test_helper.rb +58 -29
- data/test/worker_test.rb +311 -55
- metadata +157 -58
- data/init.rb +0 -1
- data/rails/init.rb +0 -1
- data/test/hoptoad_test.rb +0 -25
@@ -0,0 +1,91 @@
|
|
1
|
+
# This is an old helpers module pulled in from Resque 1.25.1
|
2
|
+
# which will be deprecated in future Resque versions. Bringing in
|
3
|
+
# this module allows us to get rid of the deprecation message
|
4
|
+
# (Resque::Helpers will be gone with no replacement in Resque 2.0.0.)
|
5
|
+
require 'multi_json'
|
6
|
+
|
7
|
+
# OkJson won't work because it doesn't serialize symbols
|
8
|
+
# in the same way yajl and json do.
|
9
|
+
if MultiJson.engine.to_s == 'MultiJson::Engines::OkJson'
|
10
|
+
fail 'Please install the yajl-ruby or json gem'
|
11
|
+
end
|
12
|
+
|
13
|
+
module Resque
|
14
|
+
module Plugins
|
15
|
+
module Loner
|
16
|
+
# Methods used by various classes in Resque.
|
17
|
+
module LegacyHelpers
|
18
|
+
class DecodeException < StandardError; end
|
19
|
+
|
20
|
+
# Direct access to the Redis instance.
|
21
|
+
def redis
|
22
|
+
Resque.redis
|
23
|
+
end
|
24
|
+
|
25
|
+
# Given a Ruby object, returns a string suitable for storage in a
|
26
|
+
# queue.
|
27
|
+
def encode(object)
|
28
|
+
::MultiJson.encode(object)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Given a string, returns a Ruby object.
|
32
|
+
def decode(object)
|
33
|
+
return unless object
|
34
|
+
|
35
|
+
begin
|
36
|
+
::MultiJson.decode(object)
|
37
|
+
rescue ::MultiJson::DecodeError => e
|
38
|
+
raise DecodeException, e.message, e.backtrace
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Given a word with dashes, returns a camel cased version of it.
|
43
|
+
#
|
44
|
+
# classify('job-name') # => 'JobName'
|
45
|
+
def classify(dashed_word)
|
46
|
+
dashed_word.split('-').each { |part| part[0] = part[0].chr.upcase }.join
|
47
|
+
end
|
48
|
+
|
49
|
+
# Tries to find a constant with the name specified in the argument string:
|
50
|
+
#
|
51
|
+
# constantize("Module") # => Module
|
52
|
+
# constantize("Test::Unit") # => Test::Unit
|
53
|
+
#
|
54
|
+
# The name is assumed to be the one of a top-level constant, no matter
|
55
|
+
# whether it starts with "::" or not. No lexical context is taken into
|
56
|
+
# account:
|
57
|
+
#
|
58
|
+
# C = 'outside'
|
59
|
+
# module M
|
60
|
+
# C = 'inside'
|
61
|
+
# C # => 'inside'
|
62
|
+
# constantize("C") # => 'outside', same as ::C
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# NameError is raised when the constant is unknown.
|
66
|
+
def constantize(camel_cased_word)
|
67
|
+
camel_cased_word = camel_cased_word.to_s
|
68
|
+
|
69
|
+
if camel_cased_word.include?('-')
|
70
|
+
camel_cased_word = classify(camel_cased_word)
|
71
|
+
end
|
72
|
+
|
73
|
+
names = camel_cased_word.split('::')
|
74
|
+
names.shift if names.empty? || names.first.empty?
|
75
|
+
|
76
|
+
constant = Object
|
77
|
+
names.each do |name|
|
78
|
+
args = Module.method(:const_get).arity != 1 ? [false] : []
|
79
|
+
|
80
|
+
if constant.const_defined?(name, *args)
|
81
|
+
constant = constant.const_get(name)
|
82
|
+
else
|
83
|
+
constant = constant.const_missing(name)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
constant
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'digest/md5'
|
2
|
+
require 'resque-loner/helpers'
|
2
3
|
|
3
4
|
#
|
4
5
|
# If you want your job to be unique, include this module in it. If you wish,
|
@@ -7,37 +8,34 @@ require 'digest/md5'
|
|
7
8
|
module Resque
|
8
9
|
module Plugins
|
9
10
|
module UniqueJob
|
10
|
-
|
11
11
|
def self.included(base)
|
12
|
-
base.extend
|
12
|
+
base.extend ClassMethods
|
13
13
|
base.class_eval do
|
14
|
-
base.send(:extend, Resque::
|
14
|
+
base.send(:extend, Resque::Plugins::Loner::LegacyHelpers)
|
15
15
|
end
|
16
16
|
end # self.included
|
17
17
|
|
18
18
|
module ClassMethods
|
19
|
-
|
20
|
-
|
21
19
|
#
|
22
20
|
# Payload is what Resque stored for this job along with the job's class name.
|
23
21
|
# On a Resque with no plugins installed, this is a hash containing :class and :args
|
24
22
|
#
|
25
23
|
def redis_key(payload)
|
26
24
|
payload = decode(encode(payload)) # This is the cycle the data goes when being enqueued/dequeued
|
27
|
-
job = payload[:class] || payload[
|
28
|
-
args = (payload[:args] || payload[
|
25
|
+
job = payload[:class] || payload['class']
|
26
|
+
args = (payload[:args] || payload['args'])
|
29
27
|
args.map! do |arg|
|
30
28
|
arg.is_a?(Hash) ? arg.sort : arg
|
31
29
|
end
|
32
30
|
|
33
|
-
digest = Digest::MD5.hexdigest
|
31
|
+
digest = Digest::MD5.hexdigest(encode(class: job, args: args))
|
34
32
|
digest
|
35
33
|
end
|
36
34
|
|
37
35
|
#
|
38
36
|
# The default ttl of a locking key is -1, i.e. forever. If for some reason you only
|
39
|
-
# want the lock to be in place after a certain amount of time, just set a ttl
|
40
|
-
# for your job. For example:
|
37
|
+
# want the lock to be in place after a certain amount of time, just set a ttl (in
|
38
|
+
# seconds) for your job. For example:
|
41
39
|
#
|
42
40
|
# class FooJob
|
43
41
|
# include Resque::Plugins::UniqueJob
|
@@ -49,9 +47,21 @@ module Resque
|
|
49
47
|
@loner_ttl || -1
|
50
48
|
end
|
51
49
|
|
50
|
+
#
|
51
|
+
# The default ttl of a persisting key is 0, i.e. immediately deleted.
|
52
|
+
# You can set loner_lock_after_execution_period if you want to block the execution
|
53
|
+
# of the job for a certain amount of time (in seconds). For example:
|
54
|
+
#
|
55
|
+
# class FooJob
|
56
|
+
# include Resque::Plugins::UniqueJob
|
57
|
+
# @loner_lock_after_execution_period = 40
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
def loner_lock_after_execution_period
|
62
|
+
@loner_lock_after_execution_period || 0
|
63
|
+
end
|
52
64
|
end # ClassMethods
|
53
|
-
|
54
|
-
|
55
65
|
end
|
56
66
|
end
|
57
67
|
end
|
@@ -60,13 +70,12 @@ module Resque
|
|
60
70
|
module Plugins
|
61
71
|
module Loner
|
62
72
|
class UniqueJob
|
63
|
-
|
64
73
|
include Resque::Plugins::UniqueJob
|
65
74
|
|
66
75
|
def self.inherited(host)
|
67
76
|
super(host)
|
68
77
|
return if @__unique_job_warned
|
69
|
-
warn
|
78
|
+
warn 'Inherit Resque::Plugins::Loner::UniqueJob is deprecated. Include Resque::Plugins::UniqueJob module instead.'
|
70
79
|
@__unique_job_warned = true
|
71
80
|
end
|
72
81
|
end
|
data/lib/resque-loner/version.rb
CHANGED
data/resque-loner.gemspec
CHANGED
@@ -5,46 +5,55 @@ $:.unshift lib unless $:.include?(lib)
|
|
5
5
|
require 'resque-loner/version'
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
|
-
s.name
|
9
|
-
s.version
|
10
|
-
s.platform
|
11
|
-
s.authors
|
12
|
-
s.email
|
13
|
-
s.homepage
|
14
|
-
s.summary
|
15
|
-
s.has_rdoc
|
8
|
+
s.name = 'resque-loner'
|
9
|
+
s.version = Resque::Plugins::Loner::VERSION
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.authors = ['Jannis Hermanns']
|
12
|
+
s.email = ['jannis@moviepilot.com']
|
13
|
+
s.homepage = 'http://github.com/jayniz/resque-loner'
|
14
|
+
s.summary = 'Adds unique jobs to resque'
|
15
|
+
s.has_rdoc = false
|
16
|
+
s.license = 'MIT'
|
16
17
|
|
17
18
|
s.rubyforge_project = 'resque-loner'
|
18
19
|
|
19
20
|
s.add_dependency 'resque', '~>1.0'
|
20
|
-
{
|
21
|
-
'rake' => '> 0.8.7',
|
22
|
-
'rack-test' => '~> 0.5.7',
|
23
|
-
'rspec' => '~> 2.5.0',
|
24
|
-
'mock_redis' => '~> 0.2.0',
|
25
|
-
'yajl-ruby' => '~> 0.8.2'
|
26
|
-
}.each do |lib, version|
|
27
|
-
s.add_development_dependency lib, version
|
28
|
-
end
|
29
21
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
22
|
+
%w(
|
23
|
+
airbrake
|
24
|
+
i18n
|
25
|
+
mocha
|
26
|
+
mock_redis
|
27
|
+
rack-test
|
28
|
+
rake
|
29
|
+
rspec
|
30
|
+
rubocop
|
31
|
+
simplecov
|
32
|
+
yajl-ruby
|
33
|
+
).each do |gemname|
|
34
|
+
s.add_development_dependency gemname
|
35
|
+
end
|
34
36
|
|
35
|
-
s.
|
36
|
-
|
37
|
+
s.executables = `git ls-files -z -- bin/*`.split("\0").map do
|
38
|
+
|f| File.basename(f)
|
39
|
+
end
|
40
|
+
s.files = `git ls-files -z`.split("\0")
|
41
|
+
s.test_files = `git ls-files -z -- {test,spec,features}/*`.split("\0")
|
42
|
+
s.require_paths = ['lib']
|
37
43
|
|
38
|
-
|
39
|
-
|
44
|
+
s.description = <<-EODESC.gsub(/^ {4}/, '')
|
45
|
+
Makes sure that for special jobs, there can be only one job with the same
|
46
|
+
workload in one queue.
|
40
47
|
|
41
|
-
|
48
|
+
Example:
|
49
|
+
class CacheSweeper
|
50
|
+
include Resque::Plugins::UniqueJob
|
42
51
|
|
43
|
-
|
52
|
+
@queue = :cache_sweeps
|
44
53
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
54
|
+
def self.perform(article_id)
|
55
|
+
# Cache Me If You Can...
|
56
|
+
end
|
57
|
+
end
|
58
|
+
EODESC
|
50
59
|
end
|
data/spec/loner_spec.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
3
|
#
|
5
4
|
# Resque-loner specific specs. I'm shooting right through the stack here and just
|
6
5
|
# test the outcomes, because the implementation will change soon and the tests run
|
@@ -11,10 +10,8 @@ class SomeJob
|
|
11
10
|
@queue = :some_queue
|
12
11
|
end
|
13
12
|
|
14
|
-
class SomeUniqueJob
|
15
|
-
|
13
|
+
class SomeUniqueJob
|
16
14
|
include Resque::Plugins::UniqueJob
|
17
|
-
|
18
15
|
@queue = :other_queue
|
19
16
|
def self.perform(foo); end
|
20
17
|
end
|
@@ -23,12 +20,11 @@ class FailingUniqueJob
|
|
23
20
|
include Resque::Plugins::UniqueJob
|
24
21
|
@queue = :other_queue
|
25
22
|
def self.perform(foo)
|
26
|
-
|
23
|
+
fail 'I beg to differ'
|
27
24
|
end
|
28
25
|
end
|
29
26
|
|
30
27
|
class DeprecatedUniqueJob < Resque::Plugins::Loner::UniqueJob
|
31
|
-
|
32
28
|
@queue = :other_queue
|
33
29
|
def self.perform(foo); end
|
34
30
|
end
|
@@ -37,11 +33,17 @@ class UniqueJobWithTtl
|
|
37
33
|
include Resque::Plugins::UniqueJob
|
38
34
|
@queue = :unique_with_ttl
|
39
35
|
@loner_ttl = 300
|
36
|
+
def self.perform(*args); end
|
37
|
+
end
|
40
38
|
|
39
|
+
class UniqueJobWithLockAfterExecution
|
40
|
+
include Resque::Plugins::UniqueJob
|
41
|
+
@queue = :unique_with_loner_lock_after_execution_period
|
42
|
+
@loner_lock_after_execution_period = 150
|
41
43
|
def self.perform(*args); end
|
42
44
|
end
|
43
45
|
|
44
|
-
describe
|
46
|
+
describe 'Resque' do
|
45
47
|
|
46
48
|
before(:each) do
|
47
49
|
Resque.redis.flushall
|
@@ -49,107 +51,107 @@ describe "Resque" do
|
|
49
51
|
Resque.size(:some_queue).should == 0
|
50
52
|
end
|
51
53
|
|
52
|
-
describe
|
53
|
-
it
|
54
|
-
Resque.enqueue SomeJob,
|
55
|
-
Resque.enqueue SomeJob,
|
54
|
+
describe 'Jobs' do
|
55
|
+
it 'can put multiple normal jobs on a queue' do
|
56
|
+
Resque.enqueue SomeJob, 'foo'
|
57
|
+
Resque.enqueue SomeJob, 'foo'
|
56
58
|
Resque.size(:some_queue).should == 2
|
57
59
|
end
|
58
60
|
|
59
|
-
it
|
60
|
-
Resque.enqueue SomeUniqueJob,
|
61
|
-
Resque.enqueue SomeUniqueJob,
|
61
|
+
it 'should allow only one of the same job to sit in a queue' do
|
62
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
63
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
62
64
|
Resque.size(:other_queue).should == 1
|
63
65
|
end
|
64
66
|
|
65
|
-
it
|
66
|
-
Resque.enqueue DeprecatedUniqueJob,
|
67
|
-
Resque.enqueue DeprecatedUniqueJob,
|
67
|
+
it 'should support deprecated Resque::Plugins::Loner::UniqueJob class' do
|
68
|
+
Resque.enqueue DeprecatedUniqueJob, 'foo'
|
69
|
+
Resque.enqueue DeprecatedUniqueJob, 'foo'
|
68
70
|
Resque.size(:other_queue).should == 1
|
69
71
|
end
|
70
72
|
|
71
|
-
it
|
72
|
-
Resque.enqueue SomeUniqueJob,
|
73
|
-
Resque.enqueue SomeUniqueJob,
|
73
|
+
it 'should allow the same jobs to be executed one after the other' do
|
74
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
75
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
74
76
|
Resque.size(:other_queue).should == 1
|
75
77
|
|
76
78
|
Resque.reserve(:other_queue)
|
77
79
|
Resque.size(:other_queue).should == 0
|
78
80
|
|
79
|
-
Resque.enqueue SomeUniqueJob,
|
80
|
-
Resque.enqueue SomeUniqueJob,
|
81
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
82
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
81
83
|
Resque.size(:other_queue).should == 1
|
82
84
|
end
|
83
85
|
|
84
|
-
it
|
85
|
-
Resque.enqueue SomeUniqueJob, :
|
86
|
-
Resque.enqueue SomeUniqueJob, :
|
86
|
+
it 'should be robust regarding hash attributes' do
|
87
|
+
Resque.enqueue SomeUniqueJob, bar: 1, foo: 2
|
88
|
+
Resque.enqueue SomeUniqueJob, foo: 2, bar: 1
|
87
89
|
Resque.size(:other_queue).should == 1
|
88
90
|
end
|
89
91
|
|
90
|
-
it
|
91
|
-
Resque.enqueue SomeUniqueJob, :
|
92
|
-
Resque.enqueue SomeUniqueJob, :bar => 1,
|
92
|
+
it 'should be robust regarding hash attributes (JSON does not distinguish between string and symbol)' do
|
93
|
+
Resque.enqueue SomeUniqueJob, bar: 1, foo: 1
|
94
|
+
Resque.enqueue SomeUniqueJob, :bar => 1, 'foo' => 1
|
93
95
|
Resque.size(:other_queue).should == 1
|
94
96
|
end
|
95
97
|
|
96
|
-
it
|
97
|
-
Resque.enqueue SomeUniqueJob,
|
98
|
-
Resque.enqueue SomeUniqueJob,
|
98
|
+
it 'should mark jobs as unqueued, when Job.destroy is killing them' do
|
99
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
100
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
99
101
|
Resque.size(:other_queue).should == 1
|
100
102
|
|
101
103
|
Resque::Job.destroy(:other_queue, SomeUniqueJob)
|
102
104
|
Resque.size(:other_queue).should == 0
|
103
105
|
|
104
|
-
Resque.enqueue SomeUniqueJob,
|
105
|
-
Resque.enqueue SomeUniqueJob,
|
106
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
107
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
106
108
|
Resque.size(:other_queue).should == 1
|
107
109
|
end
|
108
110
|
|
109
|
-
it
|
110
|
-
2.times { Resque.enqueue(
|
111
|
+
it 'should mark jobs as unqueued, when they raise an exception during #perform' do
|
112
|
+
2.times { Resque.enqueue(FailingUniqueJob, 'foo') }
|
111
113
|
Resque.size(:other_queue).should == 1
|
112
114
|
|
113
115
|
worker = Resque::Worker.new(:other_queue)
|
114
116
|
worker.work 0
|
115
117
|
Resque.size(:other_queue).should == 0
|
116
118
|
|
117
|
-
2.times { Resque.enqueue(
|
119
|
+
2.times { Resque.enqueue(FailingUniqueJob, 'foo') }
|
118
120
|
Resque.size(:other_queue).should == 1
|
119
121
|
end
|
120
122
|
|
121
|
-
it
|
122
|
-
Resque.enqueue SomeUniqueJob,
|
123
|
-
Resque.enqueued?(SomeUniqueJob,
|
124
|
-
Resque.enqueued?(SomeUniqueJob,
|
123
|
+
it 'should report if a job is queued or not' do
|
124
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
125
|
+
Resque.enqueued?(SomeUniqueJob, 'foo').should be_true
|
126
|
+
Resque.enqueued?(SomeUniqueJob, 'bar').should be_false
|
125
127
|
end
|
126
128
|
|
127
|
-
it
|
129
|
+
it 'should report if a job is in a special queue or not' do
|
128
130
|
default_queue = SomeUniqueJob.instance_variable_get(:@queue)
|
129
131
|
SomeUniqueJob.instance_variable_set(:@queue, :special_queue)
|
130
132
|
|
131
|
-
Resque.enqueue SomeUniqueJob,
|
132
|
-
Resque.enqueued_in?(
|
133
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
134
|
+
Resque.enqueued_in?(:special_queue, SomeUniqueJob, 'foo').should be_true
|
133
135
|
|
134
136
|
SomeUniqueJob.instance_variable_set(:@queue, default_queue)
|
135
137
|
|
136
|
-
Resque.enqueued?(
|
138
|
+
Resque.enqueued?(SomeUniqueJob, 'foo').should be_false
|
137
139
|
end
|
138
140
|
|
139
|
-
it
|
141
|
+
it 'should not be able to report if a non-unique job was enqueued' do
|
140
142
|
Resque.enqueued?(SomeJob).should be_nil
|
141
143
|
end
|
142
144
|
|
143
|
-
it
|
144
|
-
Resque.enqueue SomeUniqueJob,
|
145
|
-
Resque.enqueue FailingUniqueJob,
|
145
|
+
it 'should cleanup all loners when a queue is destroyed' do
|
146
|
+
Resque.enqueue SomeUniqueJob, 'foo'
|
147
|
+
Resque.enqueue FailingUniqueJob, 'foo'
|
146
148
|
|
147
149
|
Resque.remove_queue(:other_queue)
|
148
150
|
|
149
|
-
Resque.enqueue(SomeUniqueJob,
|
151
|
+
Resque.enqueue(SomeUniqueJob, 'foo')
|
150
152
|
Resque.size(:other_queue).should == 1
|
151
153
|
end
|
152
|
-
|
154
|
+
|
153
155
|
it 'should not raise an error when deleting an already empty queue' do
|
154
156
|
expect { Resque.remove_queue(:other_queue) }.to_not raise_error
|
155
157
|
end
|
@@ -157,9 +159,29 @@ describe "Resque" do
|
|
157
159
|
it 'should honor loner_ttl in the redis key' do
|
158
160
|
Resque.enqueue UniqueJobWithTtl
|
159
161
|
Resque.enqueued?(UniqueJobWithTtl).should be_true
|
160
|
-
k=Resque.redis.keys
|
162
|
+
k = Resque.redis.keys 'loners:queue:unique_with_ttl:job:*'
|
161
163
|
k.length.should == 1
|
162
164
|
Resque.redis.ttl(k[0]).should be_within(2).of(UniqueJobWithTtl.loner_ttl)
|
163
165
|
end
|
166
|
+
|
167
|
+
it 'should not allow the same job to be enqueued after execution if loner_lock_after_execution_period is set' do
|
168
|
+
Resque.enqueue UniqueJobWithLockAfterExecution, 'foo'
|
169
|
+
Resque.enqueue UniqueJobWithLockAfterExecution, 'foo'
|
170
|
+
Resque.size(:unique_with_loner_lock_after_execution_period).should == 1
|
171
|
+
|
172
|
+
Resque.reserve(:unique_with_loner_lock_after_execution_period)
|
173
|
+
Resque.size(:unique_with_loner_lock_after_execution_period).should == 0
|
174
|
+
|
175
|
+
Resque.enqueue UniqueJobWithLockAfterExecution, 'foo'
|
176
|
+
Resque.size(:unique_with_loner_lock_after_execution_period).should == 0
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'should honor loner_lock_after_execution_period in the redis key' do
|
180
|
+
Resque.enqueue UniqueJobWithLockAfterExecution
|
181
|
+
Resque.reserve(:unique_with_loner_lock_after_execution_period)
|
182
|
+
k = Resque.redis.keys 'loners:queue:unique_with_loner_lock_after_execution_period:job:*'
|
183
|
+
k.length.should == 1
|
184
|
+
Resque.redis.ttl(k[0]).should be_within(2).of(UniqueJobWithLockAfterExecution.loner_lock_after_execution_period)
|
185
|
+
end
|
164
186
|
end
|
165
187
|
end
|