resque-exponential-backoff 0.1.1
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.
- data/LICENSE +20 -0
- data/README.md +117 -0
- data/Rakefile +24 -0
- data/lib/resque-exponential-backoff.rb +2 -0
- data/lib/resque/plugins/exponential_backoff.rb +160 -0
- data/test/exponential_backoff_test.rb +107 -0
- data/test/test_helper.rb +13 -0
- metadata +148 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Luke Antins <luke@lividpenguin.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
Software), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
resque-exponential-backoff
|
2
|
+
==========================
|
3
|
+
|
4
|
+
A [Resque][rq] plugin. Requires Resque 1.8.0 & [resque-scheduler][rqs].
|
5
|
+
|
6
|
+
resque-exponential-backoff is a plugin to add retry/exponential backoff to
|
7
|
+
your resque jobs.
|
8
|
+
|
9
|
+
Usage
|
10
|
+
-----
|
11
|
+
Simply extend your module/class with this module:
|
12
|
+
|
13
|
+
require 'resque-exponential-backoff'
|
14
|
+
|
15
|
+
class DeliverWebHook
|
16
|
+
extend Resque::Plugins::ExponentialBackoff
|
17
|
+
|
18
|
+
def self.perform(url, hook_id, hmac_key)
|
19
|
+
heavy_lifting
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
### BEFORE performing job
|
25
|
+
The job increments the number of `attempts` in redis. The first attempt == 1.
|
26
|
+
|
27
|
+
### SUCSESSFULL job
|
28
|
+
Sucsessful jobs clean up any 'attempts state' from redis.
|
29
|
+
|
30
|
+
### FAILED job
|
31
|
+
If `attempts < max_attempts` the job will be requeued. The delay between retry
|
32
|
+
attempts is determine using the backoff strategy.
|
33
|
+
|
34
|
+
*Exceptions are always passed the failure backends.*
|
35
|
+
|
36
|
+
Customise & Extend
|
37
|
+
------------------
|
38
|
+
|
39
|
+
### Defaults
|
40
|
+
|
41
|
+
If you just extend with this module and nothing else, these are the defaults:
|
42
|
+
|
43
|
+
@max_attempts = 7
|
44
|
+
|
45
|
+
# key: m = minutes, h = hours
|
46
|
+
# no delay, 1m, 10m, 1h, 3h, 6h
|
47
|
+
@backoff_strategy = [0, 60, 600, 3600, 10800, 21600]
|
48
|
+
|
49
|
+
### Job identifier/key
|
50
|
+
|
51
|
+
**n.b.** The job attempts count is incremented/stored in a redis key, the key
|
52
|
+
is built using the name of your jobs class/module and its arguments.
|
53
|
+
|
54
|
+
If you have lots of arguments, really long ones, you should consider overriding
|
55
|
+
`#identifier` to implement a more suitable custom identifier.
|
56
|
+
|
57
|
+
def self.identifier(database_id, massive_url_list, meow_purr)
|
58
|
+
"#{database_id}"
|
59
|
+
end
|
60
|
+
|
61
|
+
For the examples in this readme, the default key looks like this:
|
62
|
+
|
63
|
+
exponential-backoff:<name>:<args>
|
64
|
+
exponential-backoff:DeliverWebHook:http://lividpenguin.com-1305-cd8079192'
|
65
|
+
|
66
|
+
|
67
|
+
### Custom max attempts, backoff strategy
|
68
|
+
|
69
|
+
# 4 attempts maximum.
|
70
|
+
#
|
71
|
+
# 1st retry: no delay
|
72
|
+
# 2nd retry: 60 seconds delay
|
73
|
+
# nth retry: 2 minutes delay
|
74
|
+
class DeliverWebHook
|
75
|
+
extend Resque::Plugins::ExponentialBackoff
|
76
|
+
|
77
|
+
@max_attempts = 5
|
78
|
+
@backoff_strategy = [0, 60, 120]
|
79
|
+
|
80
|
+
def self.perform(url, hook_id, hmac_key)
|
81
|
+
heavy_lifting
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
### Custom delay handling
|
86
|
+
|
87
|
+
Override `#retry_delay_seconds` to implement your own delay handling.
|
88
|
+
|
89
|
+
class DeliverWebHook
|
90
|
+
extend Resque::Plugins::ExponentialBackoff
|
91
|
+
@max_attempts = 5
|
92
|
+
|
93
|
+
def self.perform(url, hook_id, hmac_key)
|
94
|
+
heavy_lifting
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.retry_delay_seconds
|
98
|
+
(attempts * 60) ** 2
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
Install
|
104
|
+
-------
|
105
|
+
|
106
|
+
# Once I figure out how to push to rubygems.org...
|
107
|
+
gem install resque-exponential-backoff
|
108
|
+
|
109
|
+
|
110
|
+
License
|
111
|
+
-------
|
112
|
+
Copyright (c) 2010 Luke Antins <luke@lividpenguin.com>
|
113
|
+
|
114
|
+
Released under the MIT license. See LICENSE file for details.
|
115
|
+
|
116
|
+
[rq]: http://github.com/defunkt/resque
|
117
|
+
[rqs]: http://github.com/bvandenbos/resque-scheduler
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'yard'
|
4
|
+
require 'yard/rake/yardoc_task'
|
5
|
+
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
##
|
9
|
+
# Test task.
|
10
|
+
Rake::TestTask.new(:test) do |task|
|
11
|
+
task.libs << 'lib' << 'test'
|
12
|
+
task.test_files = FileList['test/*_test.rb']
|
13
|
+
task.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# docs task.
|
18
|
+
YARD::Rake::YardocTask.new :yardoc do |t|
|
19
|
+
t.files = ['lib/**/*.rb']
|
20
|
+
t.options = ['--output-dir', "doc/",
|
21
|
+
'--files', 'LICENSE',
|
22
|
+
'--readme', 'README.md',
|
23
|
+
'--title', 'resque-exponential-backoff documentation']
|
24
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module Resque
|
2
|
+
module Plugins
|
3
|
+
##
|
4
|
+
# resque-exponential-backoff is a plugin to add retry/exponential backoff
|
5
|
+
# to your resque jobs.
|
6
|
+
#
|
7
|
+
# Simply extend your module/class with this module:
|
8
|
+
#
|
9
|
+
# require 'resque-exponential-backoff'
|
10
|
+
#
|
11
|
+
# class DeliverWebHook
|
12
|
+
# extend Resque::Plugins::ExponentialBackoff
|
13
|
+
#
|
14
|
+
# def self.perform(url, hook_id, hmac_key)
|
15
|
+
# heavy_lifting
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Or do something more custom:
|
20
|
+
#
|
21
|
+
# class DeliverWebHook
|
22
|
+
# extend Resque::Plugins::ExponentialBackoff
|
23
|
+
#
|
24
|
+
# # max number of attempts.
|
25
|
+
# @max_attempts = 4
|
26
|
+
# # retry delay in seconds.
|
27
|
+
# @backoff_strategy = [0, 60]
|
28
|
+
#
|
29
|
+
# # used to build redis key to store job attempts counter.
|
30
|
+
# def self.identifier(url, hook_id, hmac_key)
|
31
|
+
# "#{url}-#{hook_id}"
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# def self.perform(url, hook_id, hmac_key)
|
35
|
+
# heavy_lifting
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
module ExponentialBackoff
|
39
|
+
|
40
|
+
##
|
41
|
+
# @abstract You may override to implement a custom identifier,
|
42
|
+
# you should consider doing this if your job arguments
|
43
|
+
# are many/long or may not cleanly cleanly to strings.
|
44
|
+
#
|
45
|
+
# Builds an identifier using the job arguments. This identifier
|
46
|
+
# is used as part of the redis key.
|
47
|
+
#
|
48
|
+
# @param [Array] args job arguments
|
49
|
+
# @return [String] job identifier
|
50
|
+
def identifier(*args)
|
51
|
+
args.join('-')
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Builds the redis key to be used for keeping state of the job
|
56
|
+
# attempts.
|
57
|
+
#
|
58
|
+
# @return [String] redis key
|
59
|
+
def key(*args)
|
60
|
+
['exponential-backoff', name, identifier(*args)].compact.join(":")
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Maximum number of attempts we can use to successfully perform the job.
|
65
|
+
# Default value: 7
|
66
|
+
#
|
67
|
+
# @return [Fixnum] number of attempts
|
68
|
+
def max_attempts
|
69
|
+
@max_attempts ||= 7
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Number of attempts so far to try and perform the job.
|
74
|
+
# Default value: 0
|
75
|
+
#
|
76
|
+
# @return [Fixnum] number of attempts
|
77
|
+
def attempts
|
78
|
+
@attempts ||= 0
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# @abstract You may override to implement your own delay logic.
|
83
|
+
#
|
84
|
+
# Returns the number of seconds to delay until the job is tried
|
85
|
+
# again. By default, this delay is taken from the `#backoff_strategy`.
|
86
|
+
#
|
87
|
+
# @return [Number, #to_i] number of seconds to delay.
|
88
|
+
def retry_delay_seconds
|
89
|
+
backoff_strategy[attempts - 1] || backoff_strategy.last
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Default backoff strategy.
|
94
|
+
#
|
95
|
+
# 1st retry : 0 delay
|
96
|
+
# 2nd retry : 1 minute
|
97
|
+
# 3rd retry : 10 minutes
|
98
|
+
# 4th retry : 1 hour
|
99
|
+
# 5th retry : 3 hours
|
100
|
+
# 6th retry : 6 hours
|
101
|
+
#
|
102
|
+
# You can set your own backoff strategy in your job module/class:
|
103
|
+
#
|
104
|
+
# @example custom backoff strategy, in your class/module:
|
105
|
+
# @backoff_strategy = [0, 0, 120]
|
106
|
+
#
|
107
|
+
# Using this strategy, the first two retries will be immediate,
|
108
|
+
# the third and any subsequent retries will be delayed by 2 minutes.
|
109
|
+
def backoff_strategy
|
110
|
+
@backoff_strategy ||= [0, 60, 600, 3600, 10_800, 21_600]
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Called before `#perform`.
|
115
|
+
# - Initialise or increment attempts counter.
|
116
|
+
def before_perform_exponential_backoff(*args)
|
117
|
+
Resque.redis.setnx(key(*args), 0) # default to 0 if not set.
|
118
|
+
@attempts = Resque.redis.incr(key(*args)) # increment by 1.
|
119
|
+
end
|
120
|
+
|
121
|
+
##
|
122
|
+
# Called after if `#perform` was successfully.
|
123
|
+
# - Delete attempts counter from redis.
|
124
|
+
def after_perform_exponential_backoff(*args)
|
125
|
+
delete_attempts_counter(*args)
|
126
|
+
end
|
127
|
+
|
128
|
+
##
|
129
|
+
# Called if the job raises an exception.
|
130
|
+
# - Requeue the job if maximum attempts has not been reached.
|
131
|
+
def on_failure_exponential_backoff(exception, *args)
|
132
|
+
if attempts >= max_attempts
|
133
|
+
delete_attempts_counter(*args)
|
134
|
+
return
|
135
|
+
end
|
136
|
+
|
137
|
+
requeue(*args)
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# Delete the attempts counter from redis, keepin it clean ;-)
|
142
|
+
def delete_attempts_counter(*args)
|
143
|
+
Resque.redis.del(key(*args))
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Requeue the current job, immediately or delayed if `#retry_delay_seconds`
|
148
|
+
# returns grater then zero.
|
149
|
+
#
|
150
|
+
# @param [Array] args job arguments
|
151
|
+
def requeue(*args)
|
152
|
+
if retry_delay_seconds > 0
|
153
|
+
Resque.enqueue_in(retry_delay_seconds, self, *args)
|
154
|
+
else
|
155
|
+
Resque.enqueue(self, *args)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class GoodJob
|
4
|
+
extend Resque::Plugins::ExponentialBackoff
|
5
|
+
@queue = :testing
|
6
|
+
|
7
|
+
def self.perform(*args)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module BadJob
|
12
|
+
extend Resque::Plugins::ExponentialBackoff
|
13
|
+
@queue = :testing
|
14
|
+
|
15
|
+
def self.perform(*args)
|
16
|
+
raise
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module CustomBackoffStrategyJob
|
21
|
+
extend Resque::Plugins::ExponentialBackoff
|
22
|
+
@queue = :testing
|
23
|
+
@backoff_strategy = [3600, 86_400]
|
24
|
+
|
25
|
+
def self.perform(*args)
|
26
|
+
raise
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module DeliverWebHook
|
31
|
+
extend Resque::Plugins::ExponentialBackoff
|
32
|
+
@queue = :testing
|
33
|
+
|
34
|
+
def self.retry_delay_seconds
|
35
|
+
attempts * 10
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.perform(url, hook_id, hmac_key)
|
39
|
+
|
40
|
+
raise
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class ExponentialBackoffTest < Test::Unit::TestCase
|
45
|
+
def setup
|
46
|
+
Resque.redis.flushall
|
47
|
+
@worker = Resque::Worker.new(:testing)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_resque_plugin_lint
|
51
|
+
assert_nothing_raised do
|
52
|
+
Resque::Plugin.lint(Resque::Plugins::ExponentialBackoff)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_resque_version
|
57
|
+
major, minor, patch = Resque::Version.split('.')
|
58
|
+
assert_equal 1, major.to_i, 'major version does not match'
|
59
|
+
assert_operator minor.to_i, :>=, 8, 'minor version is too low'
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_good_job
|
63
|
+
Resque.enqueue(GoodJob, 1234, { :cats => :maiow }, [true, false, false])
|
64
|
+
@worker.work(0)
|
65
|
+
|
66
|
+
assert_equal 1, Resque.info[:processed]
|
67
|
+
assert_equal 0, Resque.info[:failed]
|
68
|
+
assert_equal 0, Resque.delayed_queue_schedule_size
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_retry_job
|
72
|
+
Resque.enqueue(BadJob, 1234)
|
73
|
+
@worker.work(0)
|
74
|
+
|
75
|
+
assert_equal 2, Resque.info[:processed]
|
76
|
+
assert_equal 2, Resque.info[:failed]
|
77
|
+
assert_equal 1, Resque.delayed_queue_schedule_size
|
78
|
+
# FIXME: below test can be a bit brittle when off by a second.
|
79
|
+
assert_equal Time.now.to_i + 60, Resque.delayed_queue_peek(0, 1).first
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_custom_backoff_strategy_job
|
83
|
+
Resque.enqueue(CustomBackoffStrategyJob, 1234)
|
84
|
+
Resque.enqueue(CustomBackoffStrategyJob, 1234)
|
85
|
+
@worker.work(0)
|
86
|
+
|
87
|
+
assert_equal 2, Resque.info[:processed]
|
88
|
+
assert_equal 2, Resque.info[:failed]
|
89
|
+
|
90
|
+
delayed = Resque.delayed_queue_peek(0, 2)
|
91
|
+
assert_equal Time.now.to_i + 3600, delayed.first
|
92
|
+
assert_equal Time.now.to_i + 86_400, delayed.last
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_custom_backoff_job
|
96
|
+
Resque.enqueue(DeliverWebHook, 'http://lividpenguin.com', 1305, 'cd8079192d379dc612f17c660591a6cfb05f1dda')
|
97
|
+
Resque.enqueue(DeliverWebHook, 'http://lividpenguin.com', 1305, 'cd8079192d379dc612f17c660591a6cfb05f1dda')
|
98
|
+
@worker.work(0)
|
99
|
+
|
100
|
+
assert_equal 2, Resque.info[:processed]
|
101
|
+
assert_equal 2, Resque.info[:failed]
|
102
|
+
|
103
|
+
delayed = Resque.delayed_queue_peek(0, 2)
|
104
|
+
assert_equal Time.now.to_i + 10, delayed.first
|
105
|
+
assert_equal Time.now.to_i + 20, delayed.last
|
106
|
+
end
|
107
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
rootdir = File.dirname(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift rootdir + '/test'
|
3
|
+
$LOAD_PATH.unshift rootdir + '/lib'
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'resque'
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'turn' # nicer test output.
|
10
|
+
rescue LoadError
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'resque-exponential-backoff'
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: resque-exponential-backoff
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Luke Antins
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-22 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: resque
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 8
|
30
|
+
- 0
|
31
|
+
version: 1.8.0
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: resque-scheduler
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 1
|
43
|
+
- 8
|
44
|
+
- 0
|
45
|
+
version: 1.8.0
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: hashie
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
- 2
|
58
|
+
- 0
|
59
|
+
version: 0.2.0
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: turn
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
type: :development
|
73
|
+
version_requirements: *id004
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
name: yard
|
76
|
+
prerelease: false
|
77
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
type: :development
|
85
|
+
version_requirements: *id005
|
86
|
+
description: |
|
87
|
+
A resque plugin that adds retry/exponential backoff functionality to your
|
88
|
+
resque jobs.
|
89
|
+
|
90
|
+
Simply extend your module/class with this module:
|
91
|
+
|
92
|
+
require 'resque-exponential-backoff'
|
93
|
+
|
94
|
+
class DeliverWebHook
|
95
|
+
extend Resque::Plugins::ExponentialBackoff
|
96
|
+
|
97
|
+
def self.perform(url, hook_id, hmac_key)
|
98
|
+
heavy_lifting
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
email: luke@lividpenguin.com
|
103
|
+
executables: []
|
104
|
+
|
105
|
+
extensions: []
|
106
|
+
|
107
|
+
extra_rdoc_files: []
|
108
|
+
|
109
|
+
files:
|
110
|
+
- LICENSE
|
111
|
+
- Rakefile
|
112
|
+
- README.md
|
113
|
+
- test/exponential_backoff_test.rb
|
114
|
+
- test/test_helper.rb
|
115
|
+
- lib/resque/plugins/exponential_backoff.rb
|
116
|
+
- lib/resque-exponential-backoff.rb
|
117
|
+
has_rdoc: false
|
118
|
+
homepage: http://github.com/lantins/resque-exponential-backoff
|
119
|
+
licenses: []
|
120
|
+
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
version: "0"
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
version: "0"
|
140
|
+
requirements: []
|
141
|
+
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 1.3.6
|
144
|
+
signing_key:
|
145
|
+
specification_version: 3
|
146
|
+
summary: A resque plugin, add retry/exponential backoff to your resque jobs.
|
147
|
+
test_files: []
|
148
|
+
|