Class: CongregaPlenum::RetryPolicy

Inherits:
Object
  • Object
show all
Defined in:
lib/adapters/retry_policy.rb,
sig/congrega_plenum.rbs

Overview

Controls retry attempts with exponential backoff and jitter.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configuration: CongregaPlenum.configuration) ⇒ RetryPolicy

Returns a new instance of RetryPolicy.

Parameters:

  • configuration: (Configuration) (defaults to: CongregaPlenum.configuration)


6
7
8
# File 'lib/adapters/retry_policy.rb', line 6

def initialize(configuration: CongregaPlenum.configuration)
  @configuration = configuration
end

Instance Attribute Details

#configurationConfiguration (readonly)

Returns the value of attribute configuration.

Returns:



29
30
31
# File 'lib/adapters/retry_policy.rb', line 29

def configuration
  @configuration
end

Instance Method Details

#calculate_backoff_delay(retry_count) ⇒ Float

Calculates the exponential backoff delay with jitter to avoid thundering herds when several workers hit the same failure simultaneously.

Parameters:

  • (Integer)

Returns:

  • (Float)


53
54
55
56
57
58
# File 'lib/adapters/retry_policy.rb', line 53

def calculate_backoff_delay(retry_count)
  base_delay = configuration.retry_delay
  jitter = rand(0.5..1.5).to_f

  [base_delay * (2**(retry_count - 1)) * jitter, 30.0].min
end

#handle_retry_failure(url, error) ⇒ bot

Emits the failure message and re-raises so the caller pode decidir se trata ou não.

Parameters:

Returns:

  • (bot)


43
44
45
46
47
48
49
# File 'lib/adapters/retry_policy.rb', line 43

def handle_retry_failure(url, error)
  logger.error(
    "CongregaPlenum: Falha após #{max_retries} tentativas para #{url}: #{error.message}"
  )

  raise error
end

#loggerLogger

Returns:

  • (Logger)


64
65
66
# File 'lib/adapters/retry_policy.rb', line 64

def logger
  configuration.logger
end

#max_retriesInteger

Returns:

  • (Integer)


60
61
62
# File 'lib/adapters/retry_policy.rb', line 60

def max_retries
  configuration.retries
end

#retry_request(retry_count, url, error) ⇒ void

This method returns an undefined value.

Logs the retry attempt and sleeps according to the backoff algorithm. In tests we stub this to keep them fast/deterministic.

Parameters:

  • (Integer)
  • (String)
  • (Error)


33
34
35
36
37
38
39
40
# File 'lib/adapters/retry_policy.rb', line 33

def retry_request(retry_count, url, error)
  delay = calculate_backoff_delay(retry_count)

  logger.warn(
    "CongregaPlenum: Tentativa #{retry_count}/#{max_retries} para #{url}: #{error.message}, aguardando #{delay}s"
  )
  sleep(delay)
end

#with_retries(url) ⇒ void

This method returns an undefined value.

Wraps a block with retry logic for transient network/API errors.

Parameters:

  • url (String)

    identifier used for logging

Yield Returns:

  • (Object)

    result of the successful request



14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/adapters/retry_policy.rb', line 14

def with_retries(url)
  retries = 0
  begin
    yield
  rescue ConnectionError, RateLimitError, ServerError => e
    retries += 1
    return handle_retry_failure(url, e) if retries > max_retries

    retry_request(retries, url, e)
    retry
  end
end