Module: Resque::Plugins::Retry
- Included in:
- ExponentialBackoff
- Defined in:
- lib/resque/plugins/retry.rb
Overview
If you want your job to retry on failure, simply extend your module/class with this module:
class DeliverWebHook
extend Resque::Plugins::Retry # allows 1 retry by default.
@queue = :web_hooks
def self.perform(url, hook_id, hmac_key)
heavy_lifting
end
end
Easily do something custom:
class DeliverWebHook
extend Resque::Plugins::Retry
@queue = :web_hooks
@retry_limit = 8 # default: 1
@retry_delay = 60 # default: 0
# used to build redis key, for counting job attempts.
def self.identifier(url, hook_id, hmac_key)
"#{url}-#{hook_id}"
end
def self.perform(url, hook_id, hmac_key)
heavy_lifting
end
end
Instance Method Summary collapse
-
#after_perform_retry(*args) ⇒ Object
Resque after_perform hook.
-
#args_for_retry(*args) ⇒ Array
abstract
Modify the arguments used to retry the job.
-
#before_perform_retry(*args) ⇒ Object
Resque before_perform hook.
-
#identifier(*args) ⇒ String
abstract
Builds an identifier using the job arguments.
-
#on_failure_retry(exception, *args) ⇒ Object
Resque on_failure hook.
-
#redis_retry_key(*args) ⇒ String
Builds the redis key to be used for keeping state of the job attempts.
-
#retry_attempt ⇒ Fixnum
Number of retry attempts used to try and perform the job.
-
#retry_criteria_valid?(exception, *args) ⇒ Boolean
Test if the retry criteria is valid.
-
#retry_delay ⇒ Number
abstract
Number of seconds to delay until the job is retried.
-
#retry_exception?(exception) ⇒ Boolean
Convenience method to test whether you may retry on a given exception.
-
#retry_exceptions ⇒ Array?
abstract
Controls what exceptions may be retried.
-
#retry_limit ⇒ Fixnum
Maximum number of retrys we can attempt to successfully perform the job.
-
#try_again(*args) ⇒ Object
Will retry the job.
Instance Method Details
#after_perform_retry(*args) ⇒ Object
Resque after_perform hook.
Deletes retry attempt count from Redis.
159 160 161 |
# File 'lib/resque/plugins/retry.rb', line 159 def after_perform_retry(*args) Resque.redis.del(redis_retry_key(*args)) end |
#args_for_retry(*args) ⇒ Array
Modify the arguments used to retry the job. Use this to do something other than try the exact same job again.
96 97 98 |
# File 'lib/resque/plugins/retry.rb', line 96 def args_for_retry(*args) args end |
#before_perform_retry(*args) ⇒ Object
Resque before_perform hook.
Increments and sets the ‘@retry_attempt` count.
149 150 151 152 153 |
# File 'lib/resque/plugins/retry.rb', line 149 def before_perform_retry(*args) retry_key = redis_retry_key(*args) Resque.redis.setnx(retry_key, -1) # default to -1 if not set. @retry_attempt = Resque.redis.incr(retry_key) # increment by 1. end |
#identifier(*args) ⇒ String
You may override to implement a custom identifier, you should consider doing this if your job arguments are many/long or may not cleanly cleanly to strings.
Builds an identifier using the job arguments. This identifier is used as part of the redis key.
47 48 49 50 |
# File 'lib/resque/plugins/retry.rb', line 47 def identifier(*args) args_string = args.join('-') args_string.empty? ? nil : args_string end |
#on_failure_retry(exception, *args) ⇒ Object
Resque on_failure hook.
Checks if our retry criteria is valid, if it is we try again. Otherwise the retry attempt count is deleted from Redis.
168 169 170 171 172 173 174 |
# File 'lib/resque/plugins/retry.rb', line 168 def on_failure_retry(exception, *args) if retry_criteria_valid?(exception, *args) try_again(*args) else Resque.redis.del(redis_retry_key(*args)) end end |
#redis_retry_key(*args) ⇒ String
Builds the redis key to be used for keeping state of the job attempts.
57 58 59 |
# File 'lib/resque/plugins/retry.rb', line 57 def redis_retry_key(*args) ['resque-retry', name, identifier(*args)].compact.join(":").gsub(/\s/, '') end |
#retry_attempt ⇒ Fixnum
Number of retry attempts used to try and perform the job.
The real value is kept in Redis, it is accessed and incremented using a before_perform hook.
77 78 79 |
# File 'lib/resque/plugins/retry.rb', line 77 def retry_attempt @retry_attempt ||= 0 end |
#retry_criteria_valid?(exception, *args) ⇒ Boolean
Test if the retry criteria is valid.
126 127 128 129 130 131 132 |
# File 'lib/resque/plugins/retry.rb', line 126 def retry_criteria_valid?(exception, *args) # FIXME: let people extend retry criteria, give them a chance to say no. if retry_limit > 0 return false if retry_attempt >= retry_limit end retry_exception?(exception.class) end |
#retry_delay ⇒ Number
Number of seconds to delay until the job is retried.
86 87 88 |
# File 'lib/resque/plugins/retry.rb', line 86 def retry_delay @retry_delay ||= 0 end |
#retry_exception?(exception) ⇒ Boolean
Convenience method to test whether you may retry on a given exception.
104 105 106 107 |
# File 'lib/resque/plugins/retry.rb', line 104 def retry_exception?(exception) return true if retry_exceptions.nil? !! retry_exceptions.any? { |ex| ex >= exception } end |
#retry_exceptions ⇒ Array?
Controls what exceptions may be retried.
Default: ‘nil` - this will retry all exceptions.
116 117 118 |
# File 'lib/resque/plugins/retry.rb', line 116 def retry_exceptions @retry_exceptions ||= nil end |
#retry_limit ⇒ Fixnum
Maximum number of retrys we can attempt to successfully perform the job. A retry limit of 0 or below will retry forever.
66 67 68 |
# File 'lib/resque/plugins/retry.rb', line 66 def retry_limit @retry_limit ||= 1 end |
#try_again(*args) ⇒ Object
Will retry the job.
136 137 138 139 140 141 142 143 |
# File 'lib/resque/plugins/retry.rb', line 136 def try_again(*args) if retry_delay <= 0 # If the delay is 0, no point passing it through the scheduler Resque.enqueue(self, *args_for_retry(*args)) else Resque.enqueue_in(retry_delay, self, *args_for_retry(*args)) end end |