resque-lock-retry 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,11 +8,15 @@ Resque-lock-retry is an extension to
8
8
  only one job runs at a time. In the case of locking conflicts, the job may be
9
9
  ignored or retried.
10
10
 
11
+ This plugin works best in combination with
12
+ [resque-scheduler](http://github.com/bvandenbos/resque-scheduler), but it
13
+ isn't required.
14
+
11
15
  Locked jobs
12
16
  ------------
13
17
 
14
18
  If you want only one instance of your job running at a time, extend
15
- Resque::Plugins::Locked.
19
+ `Resque::Plugins::Locked`.
16
20
 
17
21
  For example:
18
22
 
@@ -23,8 +27,8 @@ For example:
23
27
  end
24
28
  end
25
29
 
26
- While other UpdateNetworkGraph jobs will be placed on the queue, the Locked
27
- class will check Redis to see if any others are executing with the same
30
+ While other UpdateNetworkGraph jobs will be placed on the queue, the `Locked`
31
+ class will check `Redis` to see if any others are executing with the same
28
32
  arguments before beginning. If another is executing the job will be aborted.
29
33
 
30
34
  If you want to define the key yourself you can override the `lock` class
@@ -41,9 +45,9 @@ method in your subclass, e.g.
41
45
  end
42
46
  end
43
47
 
44
- The above modification will ensure only one job of class UpdateNetworkGraph is
45
- running at a time, regardless of the repo_id. Normally a job is locked using a
46
- combination of its class name and arguments.
48
+ The above modification will ensure only one job of class `UpdateNetworkGraph`
49
+ is running at a time, regardless of the `repo_id`. Normally a job is locked
50
+ using a combination of its class name and arguments.
47
51
 
48
52
  Retried jobs
49
53
  ------------
@@ -51,7 +55,7 @@ Retried jobs
51
55
  ### Locks
52
56
 
53
57
  Normally, locked jobs simply abort when a lock is encountered. If you'd like
54
- the job to try again when the lock is lifted, extend RetryOnLock.
58
+ the job to try again when the lock is lifted, extend `RetryOnLock`.
55
59
 
56
60
  For example:
57
61
 
@@ -67,7 +71,7 @@ a short delay.
67
71
 
68
72
  ### Failures
69
73
 
70
- If you'd like to retry jobs when certain exceptions happen, use RetryOnFail.
74
+ If you'd like to retry jobs when certain exceptions happen, use `RetryOnFail`.
71
75
  Then, define the types of exceptions that are ok to retry on.
72
76
 
73
77
  For example:
@@ -82,8 +86,33 @@ For example:
82
86
  end
83
87
  end
84
88
 
85
- Now, if a NetworkError (or subclass) exception is thrown while performing the
86
- job, it will be required after a short delay.
89
+ Now, if a `NetworkError` (or subclass) exception is thrown while performing
90
+ the job, it will be required after a short delay.
91
+
92
+ ### Retry strategies
93
+
94
+ Retrying comes in two flavors:
95
+
96
+ 1. [resque-scheduler](http://github.com/bvandenbos/resque-scheduler) If
97
+ Resque responds to `enqueue_in`, the job will be scheduled to perform again in
98
+ the 5 seconds.
99
+
100
+ 2. `sleep` If Resque does not respond to `enqueue_in`, then we simply sleep
101
+ for 1 second before enqueing the job. This method is NOT recommended because
102
+ it will block your worker.
103
+
104
+ To change how long to wait until the job is retried, just override
105
+ `seconds_until_retry`
106
+
107
+ class UpdateNetworkGraph
108
+ extend Resque::Plugins::RetryOnLock
109
+ def self.perform(repo_id)
110
+ heavy_lifting
111
+ end
112
+ def self.seconds_until_retry
113
+ 100
114
+ end
115
+ end
87
116
 
88
117
  ### Bonus
89
118
 
data/Rakefile CHANGED
@@ -2,15 +2,10 @@ require 'rake/testtask'
2
2
 
3
3
  task :default => :test
4
4
 
5
- def command?(command)
6
- system("type #{command} > /dev/null")
7
- end
8
-
9
5
  desc "Run the test suite"
10
6
  task :test do
11
- rg = command?(:rg)
12
7
  Dir['test/**/*_test.rb'].each do |f|
13
- rg ? sh("rg #{f}") : ruby(f)
8
+ ruby(f)
14
9
  end
15
10
  end
16
11
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -5,12 +5,12 @@ module Resque
5
5
  # Override in your subclass to control how long to wait before
6
6
  # performing this job again. Retrying comes in two flavors:
7
7
  #
8
- # 1. ResqueScheduler
9
- # If Resque responds to :enqueue_in, the job will be scheduled to
8
+ # 1. `ResqueScheduler`
9
+ # If Resque responds to `enqueue_in`, the job will be scheduled to
10
10
  # perform again in the defined number of seconds.
11
11
  #
12
- # 2. Sleep
13
- # If Resque does not respond to :enqueue_in, then we simply sleep
12
+ # 2. `sleep`
13
+ # If Resque does not respond to `enqueue_in`, then we simply sleep
14
14
  # for the defined number of seconds before enqueing the job. This
15
15
  # method is NOT recommended because it will block your worker.
16
16
  #
@@ -19,12 +19,18 @@ module Resque
19
19
  Resque.respond_to?(:enqueue_in) ? 5 : 1
20
20
  end
21
21
 
22
+ # Modify the arguments used to requeue the job. Use this to do something
23
+ # other than try the exact same job again.
24
+ def args_for_try_again(*args)
25
+ args
26
+ end
27
+
22
28
  def try_again(*args)
23
29
  if Resque.respond_to?(:enqueue_in)
24
- Resque.enqueue_in(seconds_until_retry || 0, self, *args)
30
+ Resque.enqueue_in(seconds_until_retry || 0, self, *args_for_try_again(*args))
25
31
  else
26
32
  sleep(seconds_until_retry) if seconds_until_retry
27
- Resque.enqueue(self, *args)
33
+ Resque.enqueue(self, *args_for_try_again(*args))
28
34
  end
29
35
  end
30
36
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{resque-lock-retry}
8
- s.version = "0.0.1"
8
+ s.version = "0.0.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ryan Carver"]
12
- s.date = %q{2010-04-04}
12
+ s.date = %q{2010-04-09}
13
13
  s.email = %q{ryan@typekit.com}
14
14
  s.extra_rdoc_files = [
15
15
  "README.markdown"
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/test_helper'
3
3
  class Resque::CombinedTest < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- Resque.redis.flush_all
6
+ Resque.redis.flushall
7
7
  end
8
8
 
9
9
  def test_lock_on_fail_with_lock_on_retry
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/test_helper'
3
3
  class Resque::LockedJobTest < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- Resque.redis.flush_all
6
+ Resque.redis.flushall
7
7
  end
8
8
 
9
9
  def test_lint
@@ -20,7 +20,7 @@ end
20
20
  class Resque::RetriedJobWithSleepTest < Test::Unit::TestCase
21
21
 
22
22
  def setup
23
- Resque.redis.flush_all
23
+ Resque.redis.flushall
24
24
  end
25
25
 
26
26
  def test_default_seconds_until_retry
@@ -75,4 +75,30 @@ class Resque::RetriedJobWithSleepTest < Test::Unit::TestCase
75
75
  assert_equal(0, Resque.redis.llen("queue:testqueue").to_i, "job is NOT enqueued")
76
76
  end
77
77
 
78
+ def test_job_args_are_maintained
79
+ thread = Thread.new { perform_job RetriedOnFailJob, 1, FooError }
80
+ assert_equal(0, Resque.redis.llen("queue:testqueue").to_i, "queue is empty")
81
+ begin
82
+ thread.join
83
+ assert(false, "Should have raised an exception")
84
+ rescue StandardError => e
85
+ assert_equal(FooError, e.class, e.message)
86
+ end
87
+ assert job = Resque.pop(:testqueue)
88
+ assert_equal [1, "FooError"], job["args"]
89
+ end
90
+
91
+ def test_job_args_can_be_modified
92
+ thread = Thread.new { perform_job RetriedOnFailWithDifferentArgsJob, 1, FooError }
93
+ assert_equal(0, Resque.redis.llen("queue:testqueue").to_i, "queue is empty")
94
+ begin
95
+ thread.join
96
+ assert(false, "Should have raised an exception")
97
+ rescue StandardError => e
98
+ assert_equal(FooError, e.class, e.message)
99
+ end
100
+ assert job = Resque.pop(:testqueue)
101
+ assert_equal [2, "FooError"], job["args"]
102
+ end
103
+
78
104
  end
@@ -12,7 +12,7 @@ end
12
12
  class Resque::RetriedJobWithResqueSchedulerTest < Test::Unit::TestCase
13
13
 
14
14
  def setup
15
- Resque.redis.flush_all
15
+ Resque.redis.flushall
16
16
  end
17
17
 
18
18
  def test_default_seconds_until_retry
@@ -31,4 +31,16 @@ class Resque::RetriedJobWithResqueSchedulerTest < Test::Unit::TestCase
31
31
  assert_equal([5, RetriedOnFailJob, 0, FooError], Resque.last_enqueued_in)
32
32
  end
33
33
 
34
+ def test_job_args_can_be_modified
35
+ thread = Thread.new { perform_job RetriedOnFailWithDifferentArgsJob, 0, FooError }
36
+ assert_equal(0, Resque.redis.llen("queue:testqueue").to_i, "queue is empty")
37
+ begin
38
+ thread.join
39
+ assert(false, "Should have raised an exception")
40
+ rescue StandardError => e
41
+ assert_equal(FooError, e.class, e.message)
42
+ end
43
+ assert_equal([5, RetriedOnFailWithDifferentArgsJob, 1, FooError], Resque.last_enqueued_in)
44
+ end
45
+
34
46
  end
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/test_helper'
3
3
  class Resque::RetriedOnFailJobTest < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- Resque.redis.flush_all
6
+ Resque.redis.flushall
7
7
  end
8
8
 
9
9
  def test_lint
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/test_helper'
3
3
  class Resque::RetriedOnLockJobTest < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
- Resque.redis.flush_all
6
+ Resque.redis.flushall
7
7
  end
8
8
 
9
9
  def test_lint
@@ -127,6 +127,24 @@ class RetriedOnFailJob
127
127
  end
128
128
  end
129
129
 
130
+ class RetriedOnFailWithDifferentArgsJob
131
+ extend ::Resque::Plugins::RetryOnFail
132
+ @queue = :testqueue
133
+ def self.perform(sleep_time, ex)
134
+ sleep sleep_time
135
+ raise ex
136
+ end
137
+ def self.args_for_try_again(sleep_time, ex)
138
+ [sleep_time + 1, ex]
139
+ end
140
+ def self.retried_exceptions
141
+ [FooError, BarError]
142
+ end
143
+ def self.lock(*args)
144
+ "TestLock"
145
+ end
146
+ end
147
+
130
148
  class RetriedOnLockAndFailJob
131
149
  extend ::Resque::Plugins::RetryOnLock
132
150
  extend ::Resque::Plugins::RetryOnFail
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ryan Carver
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-04 00:00:00 -07:00
17
+ date: 2010-04-09 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency