Class: Shoryuken::Middleware::Server::ExponentialBackoffRetry

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/shoryuken/middleware/server/exponential_backoff_retry.rb

Overview

Middleware that implements exponential backoff retry for failed messages. When a job fails, the message visibility timeout is adjusted based on configured retry intervals.

Instance Method Summary collapse

Methods included from Util

#elapsed, #fire_event, #logger, #unparse_queues, #worker_name

Instance Method Details

#call(worker, _queue, sqs_msg, _body) { ... } ⇒ void

This method returns an undefined value.

Processes a message with exponential backoff retry on failure

Parameters:

  • worker (Object)

    the worker instance

  • _queue (String)

    the queue name (unused)

  • sqs_msg (Shoryuken::Message, Array<Shoryuken::Message>)

    the message or batch

  • _body (Object)

    the parsed message body (unused)

Yields:

  • continues to the next middleware in the chain

Raises:

  • (StandardError)

    re-raises the original exception if retry intervals are not configured or if retry limit is exceeded



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/shoryuken/middleware/server/exponential_backoff_retry.rb', line 22

def call(worker, _queue, sqs_msg, _body)
  return yield unless worker.class.exponential_backoff?

  if sqs_msg.is_a?(Array)
    logger.warn { "Exponential backoff isn't supported for batch workers" }
    return yield
  end

  started_at = Time.now
  yield
rescue => e
  retry_intervals = worker.class.get_shoryuken_options['retry_intervals']

  if retry_intervals.nil? || !handle_failure(sqs_msg, started_at, retry_intervals)
    # Re-raise the exception if the job is not going to be exponential backoff retried.
    # This allows custom middleware (like exception notifiers) to be aware of the unhandled failure.
    raise
  end

  logger.warn { "Message #{sqs_msg.message_id} will attempt retry due to error: #{e.message}" }
  # since we didn't raise, lets log the backtrace for debugging purposes.
  logger.debug { e.backtrace.join("\n") } unless e.backtrace.nil?
end