Skip to content

Instantly share code, notes, and snippets.

@bpo
Created March 22, 2010 22:36
Show Gist options
  • Save bpo/340622 to your computer and use it in GitHub Desktop.
Save bpo/340622 to your computer and use it in GitHub Desktop.
require 'resque_scheduler'
module Resque
module Failure
##
# Support for automatically retrying jobs after the fashion of
# Delayed::Job.
class AutoRetry < Base
extend Helpers
##
# require 'resque/failure/auto_retry'
#
# Resque::Failure.backend = Resque::Failure::AutoRetry
# Resque::Failure::AutoRetry.backend = Resque::Failure::Hoptoad
#
# AutoRetry's backend support is used after a job fails repeated
# retries.
attr_accessor :attempts, :id
@queue = :low
def self.backend=(backend)
@backend = backend
end
# Returns the current backend class. If none has been set, falls
# back to `Resque::Failure::Redis`
def self.backend
return @backend if @backend
require 'resque/failure/redis'
@backend = Failure::Redis
end
def count
backend.count
end
def all(start = 0, count = 1)
backend.all(start, count)
end
def url
backend.url
end
def self.max=(max)
@max = max
end
def self.max
@max ||= 10
end
#
# resque execution of delayed payloads
#
def self.perform(attempts, payload)
Resque.constantize(payload['class']).perform(*payload['args'])
end
#
# failure handling
#
def save
unwrap_payload
attempts < AutoRetry.max ? try_again : give_up
end
def try_again
delay = (attempts ** 4) + 5
log "Scheduling #{payload.inspect} for execution in #{delay}s after #{attempts} attempts."
Resque.enqueue_at(Time.now + delay, self.class, attempts, payload)
end
def give_up
log "Giving up on #{payload.inspect} after #{attempts} attempts."
AutoRetry.backend.new(exception, worker, queue, payload).save
end
def unwrap_payload
if payload["class"] == self.class.to_s
self.attempts = self.payload["args"].shift.to_i + 1
self.payload = self.payload["args"].shift
else
self.attempts = 1
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment