Method: Resque::Failure::MultipleWithRetrySuppression#save

Defined in:
lib/resque/failure/multiple_with_retry_suppression.rb

#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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/resque/failure/multiple_with_retry_suppression.rb', line 29

def save
  args = args_from(payload)

  log_message 'failure backend save', args, 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,
      exception
    )

    cleanup_retry_failure_log!
    return super
  end

  # some plugins define retry_delay and have it take no arguments, so rather than break those,
  # we'll just check here to see whether it takes the additional exception class argument or not
  # we also allow all job args to be passed to a custom `retry_delay` method
  retry_delay_arity = klass.method(:retry_delay).arity

  calculated_retry_delay = if [-2, 2].include?(retry_delay_arity)
    klass.retry_delay(exception.class, *args)
  elsif [-1, 1].include?(retry_delay_arity)
    klass.retry_delay(exception.class)
  else
    klass.retry_delay
  end

  if calculated_retry_delay > 0
    log_message(
      "retry_delay: #{calculated_retry_delay} > 0 - saving details in Redis",
      args,
      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 * calculated_retry_delay,
      data
    )
  else
    log_message(
      "retry_delay: #{calculated_retry_delay} <= 0 - ignoring",
      args,
      exception
    )
  end
end