Class: Resque::Failure::MultipleWithRetrySuppression

Inherits:
Multiple
  • Object
show all
Includes:
Plugins::Retry::Logging
Defined in:
lib/resque/failure/multiple_with_retry_suppression.rb

Overview

A multiple failure backend, with retry suppression

For example: if you had a job that could retry 5 times, your failure backends are not notified unless the final retry attempt also fails.

Example:

require 'resque-retry'
require 'resque/failure/redis'

Resque::Failure::MultipleWithRetrySuppression.classes = [Resque::Failure::Redis]
Resque::Failure.backend = Resque::Failure::MultipleWithRetrySuppression

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Plugins::Retry::Logging

#log_message

Class Method Details

.failure_key(retry_key) ⇒ Object

Expose this for the hook’s use



79
80
81
# File 'lib/resque/failure/multiple_with_retry_suppression.rb', line 79

def self.failure_key(retry_key)
  'failure-' + retry_key
end

.requeue_queue(queue) ⇒ Object

Monkey-patch this in for now since it is a hard requirement for the “retry-all” functionality to work via the Web UI.

This can be removed when the following PR has been merged into ‘Resque` itself:

github.com/resque/resque/pull/1659



92
93
94
# File 'lib/resque/failure/multiple_with_retry_suppression.rb', line 92

def self.requeue_queue(queue)
  classes.first.requeue_queue(queue)
end

Instance Method Details

#saveObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Called when the job fails

If the job will retry, suppress the failure from the other backends. Store the lastest failure information in redis, used by the web interface.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/resque/failure/multiple_with_retry_suppression.rb', line 29

def save
  log_message 'failure backend save', args_from(payload), exception

  retryable = retryable?
  job_being_retried = retryable && retrying?

  if !job_being_retried
    log_message(
      "#{retryable ? '' : 'non-'}retryable job is not being retried - sending failure to superclass",
      args_from(payload),
      exception
    )

    cleanup_retry_failure_log!
    super
  elsif retry_delay > 0
    log_message(
      "retry_delay: #{retry_delay} > 0 - saving details in Redis",
      args_from(payload),
      exception
    )

    data = {
      :failed_at => Time.now.strftime("%Y/%m/%d %H:%M:%S"),
      :payload   => payload,
      :exception => exception.class.to_s,
      :error     => exception.to_s,
      :backtrace => Array(exception.backtrace),
      :worker    => worker.to_s,
      :queue     => queue
    }
    data = Resque.encode(data)

    Resque.redis.setex(
      failure_key,
      2 * retry_delay,
      data
    )
  else
    log_message(
      "retry_delay: #{retry_delay} <= 0 - ignoring",
      args_from(payload),
      exception
    )
  end
end