Class: Agentic::RetryHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/agentic/retry_handler.rb

Overview

Handles retrying operations with configurable backoff strategies

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_retries: 3, retryable_errors: [Errors::LlmTimeoutError, Errors::LlmRateLimitError, Errors::LlmServerError, Errors::LlmNetworkError], backoff_strategy: :exponential, backoff_options: {}, before_retry: nil, after_retry: nil) ⇒ RetryHandler

Initializes a new RetryHandler

Options Hash (backoff_options:):

  • :base_delay (Float)

    The base delay in seconds

  • :jitter_factor (Float)

    The jitter factor (0.0-1.0)



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/agentic/retry_handler.rb', line 30

def initialize(
  max_retries: 3,
  retryable_errors: [Errors::LlmTimeoutError, Errors::LlmRateLimitError, Errors::LlmServerError, Errors::LlmNetworkError],
  backoff_strategy: :exponential,
  backoff_options: {},
  before_retry: nil,
  after_retry: nil
)
  @max_retries = max_retries
  @retryable_errors = retryable_errors
  @backoff_strategy = backoff_strategy
  @backoff_options = {
    base_delay: 1.0,
    jitter_factor: 0.25
  }.merge(backoff_options)
  @before_retry = before_retry
  @after_retry = after_retry
end

Instance Attribute Details

#after_retryProc? (readonly)



19
20
21
# File 'lib/agentic/retry_handler.rb', line 19

def after_retry
  @after_retry
end

#backoff_strategySymbol (readonly)



13
14
15
# File 'lib/agentic/retry_handler.rb', line 13

def backoff_strategy
  @backoff_strategy
end

#before_retryProc? (readonly)



16
17
18
# File 'lib/agentic/retry_handler.rb', line 16

def before_retry
  @before_retry
end

#max_retriesInteger (readonly)



7
8
9
# File 'lib/agentic/retry_handler.rb', line 7

def max_retries
  @max_retries
end

#retryable_errorsArray<Class, String> (readonly)



10
11
12
# File 'lib/agentic/retry_handler.rb', line 10

def retryable_errors
  @retryable_errors
end

Instance Method Details

#with_retry(&block) ⇒ Object

Executes the given block with retries

Raises:

  • (StandardError)

    If the block failed after all retries



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
# File 'lib/agentic/retry_handler.rb', line 53

def with_retry(&block)
  attempt = 0

  begin
    attempt += 1
    block.call
  rescue => e
    error = e.is_a?(Errors::LlmError) ? e : Errors::LlmError.new(e.message, context: {original_error: e.class.name})

    if retryable?(error) && attempt <= max_retries
      delay = calculate_backoff_delay(attempt)
      Agentic.logger.info("Retry #{attempt}/#{max_retries} for error: #{error.message}. Waiting #{delay.round(2)}s before retrying.")

      @before_retry&.call(attempt: attempt, error: error, delay: delay)
      sleep(delay)
      @after_retry&.call(attempt: attempt, error: error, delay: delay)

      retry
    else
      if attempt > max_retries
        Agentic.logger.error("Max retries (#{max_retries}) exceeded for error: #{error.message}")
      else
        Agentic.logger.error("Non-retryable error: #{error.message}")
      end

      raise error
    end
  end
end