Class: ComplyanceSDK::Retry::RetryStrategy
- Inherits:
-
Object
- Object
- ComplyanceSDK::Retry::RetryStrategy
- Defined in:
- lib/complyance_sdk/retry/retry_strategy.rb
Overview
Advanced retry strategy with exponential backoff, jitter, and circuit breaker Ruby equivalent of the Java RetryStrategy
Instance Attribute Summary collapse
-
#circuit_breaker ⇒ Object
readonly
Returns the value of attribute circuit_breaker.
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
Instance Method Summary collapse
-
#circuit_breaker_state ⇒ Symbol?
Get the current circuit breaker state (for monitoring).
-
#circuit_breaker_stats ⇒ String
Get circuit breaker statistics (for monitoring).
-
#execute(operation_name = 'operation', context = {}) { ... } ⇒ Object
Execute a block with retry logic.
-
#initialize(config, circuit_breaker = nil, logger = nil) ⇒ RetryStrategy
constructor
Initialize a new retry strategy.
-
#reset_circuit_breaker! ⇒ Object
Reset the circuit breaker (for testing/administrative purposes).
Constructor Details
#initialize(config, circuit_breaker = nil, logger = nil) ⇒ RetryStrategy
Initialize a new retry strategy
17 18 19 20 21 |
# File 'lib/complyance_sdk/retry/retry_strategy.rb', line 17 def initialize(config, circuit_breaker = nil, logger = nil) @config = config @circuit_breaker = circuit_breaker @logger = logger || Logger.new(STDOUT) end |
Instance Attribute Details
#circuit_breaker ⇒ Object (readonly)
Returns the value of attribute circuit_breaker.
10 11 12 |
# File 'lib/complyance_sdk/retry/retry_strategy.rb', line 10 def circuit_breaker @circuit_breaker end |
#config ⇒ Object (readonly)
Returns the value of attribute config.
10 11 12 |
# File 'lib/complyance_sdk/retry/retry_strategy.rb', line 10 def config @config end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
10 11 12 |
# File 'lib/complyance_sdk/retry/retry_strategy.rb', line 10 def logger @logger end |
Instance Method Details
#circuit_breaker_state ⇒ Symbol?
Get the current circuit breaker state (for monitoring)
108 109 110 |
# File 'lib/complyance_sdk/retry/retry_strategy.rb', line 108 def circuit_breaker_state @circuit_breaker&.state end |
#circuit_breaker_stats ⇒ String
Get circuit breaker statistics (for monitoring)
115 116 117 118 119 120 121 122 |
# File 'lib/complyance_sdk/retry/retry_strategy.rb', line 115 def circuit_breaker_stats if @circuit_breaker stats = @circuit_breaker.stats "CircuitBreaker{state=#{stats[:state]}, failures=#{stats[:failure_count]}, last_failure=#{stats[:last_failure_time]}}" else 'Circuit breaker disabled' end end |
#execute(operation_name = 'operation', context = {}) { ... } ⇒ Object
Execute a block with retry logic
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 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/complyance_sdk/retry/retry_strategy.rb', line 29 def execute(operation_name = 'operation', context = {}) attempt = 1 last_exception = nil while attempt <= @config.max_attempts begin @logger.debug("Attempting operation '#{operation_name}' (attempt #{attempt}/#{@config.max_attempts})") result = if @circuit_breaker @circuit_breaker.execute { yield } else yield end if attempt > 1 @logger.info("Operation '#{operation_name}' succeeded on attempt #{attempt}") end return result rescue ComplyanceSDK::Exceptions::SDKException => e last_exception = e # Check if this error should be retried unless should_retry?(e, attempt) @logger.debug("Operation '#{operation_name}' failed with non-retryable error: #{e.}") raise e end # If this was the last attempt, don't wait break if attempt >= @config.max_attempts # Calculate delay and wait delay = calculate_delay(attempt) @logger.warn("Operation '#{operation_name}' failed on attempt #{attempt} (#{e.}), retrying in #{(delay * 1000).round}ms") sleep(delay) rescue => e # Handle non-SDK exceptions @logger.error("Unexpected error in operation '#{operation_name}': #{e.}") error_detail = { code: :processing_error, message: "Unexpected error: #{e.}", suggestion: "This appears to be an unexpected error. Please contact support if it persists", context: { original_exception: e.class.name } } raise ComplyanceSDK::Exceptions::SDKException.new( "Unexpected error: #{e.}", context: error_detail ) end attempt += 1 end # All retries exhausted @logger.error("Operation '#{operation_name}' failed after #{@config.max_attempts} attempts") if last_exception raise last_exception else error_detail = { code: :max_retries_exceeded, message: "Max retries exceeded", suggestion: "Operation failed after #{@config.max_attempts} attempts", context: { attempts: @config.max_attempts } } raise ComplyanceSDK::Exceptions::SDKException.new( "Max retries exceeded", context: error_detail ) end end |
#reset_circuit_breaker! ⇒ Object
Reset the circuit breaker (for testing/administrative purposes)
125 126 127 128 129 130 131 132 |
# File 'lib/complyance_sdk/retry/retry_strategy.rb', line 125 def reset_circuit_breaker! if @circuit_breaker @circuit_breaker.reset! @logger.info('Circuit breaker reset') else @logger.warn('Circuit breaker reset requested but no circuit breaker configured') end end |