resque-unique_at_runtime 2.0.1 → 2.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4df741e7e76af4475e15a3f2fd4a820bc64fb535
4
- data.tar.gz: '05833f9f5ecea8a7513df2f8ebef479b52c3c5db'
3
+ metadata.gz: 3d3d6b55df9f56bfc4706242b0d7f1f6e47fae6d
4
+ data.tar.gz: 816c4042916af3a170e6af35b1978f4f2a3cc338
5
5
  SHA512:
6
- metadata.gz: 7734660f78f5626ec08f83a36504b8e14d2019226b772463937cdba0b8645cddecf005ea7262dc313a8f38b97c0982579c244235c51219b6ebe337282060a133
7
- data.tar.gz: 857a0e636da5f0ea235e0c73ca93c3a75794e440a6fb5226d1821bf7210060f44ac35ebf3478623ac4c61bb6b45e02a6da8c22b2b7450a69a75a6f92cb80509e
6
+ metadata.gz: c61abb7166768391285d3a0478a23d0b63564c134969cd099fd69c05b5cdd2f156aaf529b8b859e91bd40627beb258abb2b4c4d81ba2cc9e678314df92c8cce2
7
+ data.tar.gz: d900c6c92ad2cf28f94872ae014044b821ec488b974e78428bfdcec3cfc81ed3c069d93211cdccf06d625b0e47242d7c45a332a326d6291b65a0ffdfbf6108d7
data/.travis.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - 2.1.0
3
+ - 2.2.8
4
+ - 2.3.5
5
+ - 2.4.2
data/README.md CHANGED
@@ -165,7 +165,7 @@ process pegging a CPU/core on a worker server. To guard against this, the
165
165
  default behavior is to sleep for 1 second before the requeue, which will allow
166
166
  the cpu to perform other work.
167
167
 
168
- This can be customized using a ```@requeue_interval``` class instance variable
168
+ This can be customized using a ```@runtime_requeue_interval``` class instance variable
169
169
  in your job like so:
170
170
 
171
171
 
@@ -175,7 +175,7 @@ in your job like so:
175
175
  extend Resque::Plugins::UniqueAtRuntime
176
176
 
177
177
  @queue = :serial_work
178
- @requeue_interval = 5 # sleep for 5 seconds before requeueing
178
+ @runtime_requeue_interval = 5 # sleep for 5 seconds before requeueing
179
179
 
180
180
  def self.perform
181
181
  # some implementation
@@ -1,7 +1,7 @@
1
1
  module Resque
2
2
  module Plugins
3
3
  module UniqueAtRuntime
4
- VERSION = "2.0.1"
4
+ VERSION = "2.0.2"
5
5
  end
6
6
  end
7
7
  end
@@ -3,62 +3,86 @@ require 'resque-unique_at_runtime/version'
3
3
  module Resque
4
4
  module Plugins
5
5
  module UniqueAtRuntime
6
- LOCK_TIMEOUT = 60 * 60 * 24 * 5 # 5 days
6
+ def runtime_lock_timeout_at(now)
7
+ now + runtime_lock_timeout + 1
8
+ end
7
9
 
8
- def lock_timeout
9
- Time.now.to_i + LOCK_TIMEOUT + 1
10
+ def runtime_lock_timeout
11
+ self.instance_variable_get(:@runtime_lock_timeout) || 60 * 60 * 24 * 5
10
12
  end
11
13
 
12
- def requeue_interval
13
- self.instance_variable_get(:@requeue_interval) || 1
14
+ def runtime_requeue_interval
15
+ self.instance_variable_get(:@runtime_requeue_interval) || 1
14
16
  end
15
17
 
16
18
  # Overwrite this method to uniquely identify which mutex should be used
17
19
  # for a resque worker.
18
20
  def unique_at_runtime_redis_key(*_)
19
- "unique_at_runtime:#{@queue}"
21
+ puts "resque-unique_at_runtime: getting key for #{@queue}!" if ENV['RESQUE_DEBUG']
22
+ "resque-unique_at_runtime:#{@queue}"
20
23
  end
21
24
 
22
25
  def can_lock_queue?(*args)
26
+ queue_locked?(*args) == false ? true : false
27
+ end
28
+
29
+ def queue_locked?(*args)
23
30
  now = Time.now.to_i
24
31
  key = unique_at_runtime_redis_key(*args)
25
- timeout = lock_timeout
32
+ timeout = runtime_lock_timeout_at(now)
33
+
34
+ puts "resque-unique_at_runtime: attempting to lock queue with #{key}" if ENV['RESQUE_DEBUG']
26
35
 
27
36
  # Per http://redis.io/commands/setnx
28
- return true if Resque.redis.setnx(key, timeout)
29
- return false if Resque.redis.get(key).to_i > now
30
- return true if Resque.redis.getset(key, timeout).to_i <= now
31
- return false
37
+ return false if Resque.redis.setnx(key, timeout)
38
+ return key if Resque.redis.get(key).to_i > now
39
+ return false if Resque.redis.getset(key, timeout).to_i <= now
40
+ return key
32
41
  end
33
42
 
34
43
  def unlock_queue(*args)
35
- Resque.redis.del(unique_at_runtime_redis_key(*args))
44
+ key = unique_at_runtime_redis_key(*args)
45
+ puts "resque-unique_at_runtime: unlock queue with #{key}" if ENV['RESQUE_DEBUG']
46
+ Resque.redis.del(key)
36
47
  end
37
48
 
38
49
  def reenqueue(*args)
39
50
  Resque.enqueue(self, *args)
40
51
  end
41
52
 
42
- def before_perform(*args)
43
- unless can_lock_queue?(*args)
53
+ def before_perform_lock_runtime(*args)
54
+ if (key = queue_locked?(*args))
55
+ puts "resque-unique_at_runtime: failed to lock queue with #{key}" if ENV['RESQUE_DEBUG']
56
+
44
57
  # Sleep so the CPU's rest
45
- sleep(requeue_interval)
58
+ sleep(runtime_requeue_interval)
46
59
 
47
60
  # can't get the lock, so re-enqueue the task
48
61
  reenqueue(*args)
49
62
 
50
63
  # and don't perform
51
64
  raise Resque::Job::DontPerform
65
+ else
66
+ puts "will perform"
67
+ true
52
68
  end
53
69
  end
54
70
 
55
- def around_perform(*args)
71
+ def around_perform_unlock_runtime(*args)
56
72
  begin
57
73
  yield
58
74
  ensure
59
75
  unlock_queue(*args)
60
76
  end
61
77
  end
78
+
79
+ # There may be scenarios where the around_perform's ensure unlock
80
+ # duplicates the on_failure unlock, but that's a small price to pay for
81
+ # uniqueness.
82
+ def on_failure_unlock_runtime(*args)
83
+ puts "resque-unique_at_runtime: on failure unlock" if ENV['RESQUE_DEBUG']
84
+ unlock_queue(*args)
85
+ end
62
86
  end
63
87
  end
64
88
  end
@@ -23,14 +23,14 @@ describe Resque::Plugins::UniqueAtRuntime do
23
23
  Resque.redis.flushall
24
24
  end
25
25
 
26
- describe ".requeue_interval" do
26
+ describe ".runtime_requeue_interval" do
27
27
  it "should default to 5" do
28
- expect(SerialJob.requeue_interval).to eql(1)
28
+ expect(SerialJob.runtime_requeue_interval).to eql(1)
29
29
  end
30
30
 
31
31
  it "should be overridable with a class instance var" do
32
- SerialJob.instance_variable_set(:@requeue_interval, 5)
33
- expect(SerialJob.requeue_interval).to eql(5)
32
+ SerialJob.instance_variable_set(:@runtime_requeue_interval, 5)
33
+ expect(SerialJob.runtime_requeue_interval).to eql(5)
34
34
  end
35
35
  end
36
36
 
@@ -78,7 +78,7 @@ describe Resque::Plugins::UniqueAtRuntime do
78
78
 
79
79
  describe ".perform" do
80
80
  before do
81
- SerialJob.instance_variable_set(:@requeue_interval, 0)
81
+ SerialJob.instance_variable_set(:@runtime_requeue_interval, 0)
82
82
  end
83
83
 
84
84
  describe "using the default redis key" do
@@ -86,7 +86,7 @@ describe Resque::Plugins::UniqueAtRuntime do
86
86
  job = Resque::Job.new(:serial_work, { 'class' => 'SerialJob', 'args' => %w[account_one job_one] })
87
87
 
88
88
  # job is the first SerialJob to run so it can lock the queue and perform
89
- expect(SerialJob).to receive(:can_lock_queue?).and_return(true)
89
+ expect(SerialJob).to receive(:queue_locked?).and_return(false)
90
90
 
91
91
  # but it should also clean up after itself
92
92
  expect(SerialJob).to receive(:unlock_queue)
@@ -98,13 +98,13 @@ describe Resque::Plugins::UniqueAtRuntime do
98
98
  job = Resque::Job.new(:serial_work, { 'class' => 'SerialJob', 'args' => %w[account_one job_one] })
99
99
 
100
100
  # job is the first SerialJob to run so it can lock the queue and perform
101
- expect(SerialJob).to receive(:can_lock_queue?).and_return(true)
101
+ expect(SerialJob).to receive(:queue_locked?).and_return(false)
102
102
 
103
103
  # but we have a catastrophic job failure
104
104
  expect(SerialJob).to receive(:perform).and_raise(Exception)
105
105
 
106
106
  # and still it should clean up after itself
107
- expect(SerialJob).to receive(:unlock_queue)
107
+ expect(SerialJob).to receive(:unlock_queue).at_least(1).times
108
108
 
109
109
  # unfortunately, the job will be lost but resque doesn't guarantee jobs
110
110
  # aren't lost
@@ -117,7 +117,7 @@ describe Resque::Plugins::UniqueAtRuntime do
117
117
  Resque::Job.create(:serial_work, 'SerialJob', job1_payload)
118
118
  Resque::Job.create(:serial_work, 'SerialJob', job2_payload)
119
119
 
120
- expect(SerialJob).to receive(:can_lock_queue?).and_return(false)
120
+ expect(SerialJob).to receive(:queue_locked?).and_return(true)
121
121
 
122
122
  # perform returns false when DontPerform exception is raised in
123
123
  # before_perform callback
@@ -134,7 +134,7 @@ describe Resque::Plugins::UniqueAtRuntime do
134
134
  job = Resque::Job.new(:serial_work, { 'class' => 'SerialJobWithCustomRedisKey', 'args' => %w[account_one job_one] })
135
135
 
136
136
  # job is the first SerialJobWithCustomRedisKey to run so it can lock the queue and perform
137
- expect(SerialJobWithCustomRedisKey).to receive(:can_lock_queue?).and_return(true)
137
+ expect(SerialJobWithCustomRedisKey).to receive(:queue_locked?).and_return(false)
138
138
 
139
139
  # but it should also clean up after itself
140
140
  expect(SerialJobWithCustomRedisKey).to receive(:unlock_queue)
@@ -146,13 +146,13 @@ describe Resque::Plugins::UniqueAtRuntime do
146
146
  job = Resque::Job.new(:serial_work, { 'class' => 'SerialJobWithCustomRedisKey', 'args' => %w[account_one job_one] })
147
147
 
148
148
  # job is the first SerialJobWithCustomRedisKey to run so it can lock the queue and perform
149
- expect(SerialJobWithCustomRedisKey).to receive(:can_lock_queue?).and_return(true)
149
+ expect(SerialJobWithCustomRedisKey).to receive(:queue_locked?).and_return(false)
150
150
 
151
151
  # but we have a catastrophic job failure
152
152
  expect(SerialJobWithCustomRedisKey).to receive(:perform).and_raise(Exception)
153
153
 
154
154
  # and still it should clean up after itself
155
- expect(SerialJobWithCustomRedisKey).to receive(:unlock_queue)
155
+ expect(SerialJobWithCustomRedisKey).to receive(:unlock_queue).at_least(1).times
156
156
 
157
157
  # unfortunately, the job will be lost but resque doesn't guarantee jobs
158
158
  # aren't lost
@@ -165,7 +165,7 @@ describe Resque::Plugins::UniqueAtRuntime do
165
165
  Resque::Job.create(:serial_work, 'SerialJobWithCustomRedisKey', job1_payload)
166
166
  Resque::Job.create(:serial_work, 'SerialJobWithCustomRedisKey', job2_payload)
167
167
 
168
- expect(SerialJobWithCustomRedisKey).to receive(:can_lock_queue?).and_return(false)
168
+ expect(SerialJobWithCustomRedisKey).to receive(:queue_locked?).and_return(true)
169
169
 
170
170
  # perform returns false when DontPerform exception is raised in
171
171
  # before_perform callback
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque-unique_at_runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-10-01 00:00:00.000000000 Z
12
+ date: 2017-11-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: resque