### Basic Circuit Breaker Integration Source: https://context7.com/wsargent/circuit_breaker/llms.txt Demonstrates how to include the CircuitBreaker module in a class and protect a method using `circuit_method`. This is the simplest way to start using the circuit breaker. ```APIDOC ## Basic Circuit Breaker Integration ### Description Include the CircuitBreaker module in any class and mark methods to be protected with the circuit breaker pattern. This example shows how to protect a `charge_credit_card` method in a `PaymentService`. ### Method `circuit_method :method_name` ### Endpoint N/A (This is a Ruby library integration, not a network endpoint) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```ruby require 'circuit_breaker' class PaymentService include CircuitBreaker def charge_credit_card(amount, card_number) # Simulate external API call response = HTTPClient.post("https://payment-api.example.com/charge", { amount: amount, card: card_number }) return response.body end # Protect the method with circuit breaker circuit_method :charge_credit_card end # Usage service = PaymentService.new # First few calls succeed begin result = service.charge_credit_card(100, "4111111111111111") puts "Payment successful: #{result}" rescue => e puts "Payment failed: #{e.message}" end # After multiple failures, circuit opens # CircuitBreaker::CircuitBrokenException will be raised ``` ### Response #### Success Response (200) Returns the successful result of the wrapped method. #### Response Example ```json "Payment processed successfully" ``` #### Error Response `CircuitBreaker::CircuitBrokenException` is raised when the circuit is open. #### Error Response Example ```json { "error": "Circuit is open. Calls are failing immediately." } ``` ``` -------------------------------- ### Implement Custom Circuit Handler in Ruby Source: https://context7.com/wsargent/circuit_breaker/llms.txt This example shows how to extend the circuit breaker functionality by implementing a custom circuit handler class in Ruby. It overrides `on_failure` and `on_success` methods to add custom logic, such as sending alerts or notifications when the circuit state changes. ```ruby require 'circuit_breaker' class CustomCircuitHandler < CircuitBreaker::CircuitHandler attr_accessor :notification_service def initialize(logger = nil) super(logger) @notification_service = nil end # Override to add custom behavior when circuit trips def on_failure(circuit_state) super(circuit_state) # Send alert when circuit trips if trip_checker.tripped?(circuit_state) @logger.warn("ALERT: Circuit breaker tripped!") if @logger @notification_service.send_alert("Circuit breaker opened") if @notification_service end end # Override to add custom behavior when circuit recovers def on_success(circuit_state) was_half_open = circuit_state.half_open? super(circuit_state) # Send recovery notification if was_half_open && circuit_state.closed? @logger.info("Circuit breaker recovered") if @logger @notification_service.send_alert("Circuit breaker closed") if @notification_service end end end class CriticalService include CircuitBreaker def perform_critical_operation(data) # Important business logic api_response = HTTPClient.post("https://critical-api.example.com/process", data) api_response.body end circuit_method :perform_critical_operation # Use custom handler instead of default circuit_handler_class CustomCircuitHandler circuit_handler do |handler| handler.logger = Logger.new(STDOUT) handler.failure_threshold = 2 handler.failure_timeout = 60 handler.notification_service = NotificationService.new end end service = CriticalService.new # Custom handler will send notifications when circuit state changes 5.times do |i| begin result = service.perform_critical_operation({job_id: i}) puts "Operation #{i} completed" rescue => e puts "Operation #{i} failed: #{e.message}" end sleep 1 end # Custom notifications sent on circuit trip and recovery # Allows integration with monitoring and alerting systems ``` -------------------------------- ### Monitor Circuit Breaker State in Ruby Source: https://context7.com/wsargent/circuit_breaker/llms.txt This Ruby code snippet shows how to access and monitor the state of a circuit breaker. It provides an example of a `health_check` function that retrieves the circuit's status, failure count, call count, and last failure time, useful for dashboards or health checks. ```ruby require 'circuit_breaker' class ApiClient include CircuitBreaker def call_api(endpoint) response = HTTPClient.get("https://api.example.com#{endpoint}") JSON.parse(response.body) end circuit_method :call_api circuit_handler do |handler| handler.failure_threshold = 5 handler.failure_timeout = 10 handler.invocation_timeout = 5 end end client = ApiClient.new # Health check endpoint implementation def health_check(client) state = client.circuit_state health_info = { status: state.aasm_state, # :closed, :open, or :half_open failure_count: state.failure_count, call_count: state.call_count, last_failure_time: state.last_failure_time, is_healthy: state.closed? } if state.open? || state.half_open? health_info[:failure_rate] = (state.failure_count.to_f / state.call_count * 100).round(2) health_info[:time_until_retry] = 10 - (Time.now - state.last_failure_time) end health_info end ``` -------------------------------- ### Exclude Specific Exceptions from Circuit Breaker Failures in Ruby Source: https://context7.com/wsargent/circuit_breaker/llms.txt This Ruby example shows how to configure a circuit breaker to ignore specific exception types, preventing them from counting towards the failure threshold. It defines custom error classes and applies them to the `excluded_exceptions` handler option. This is useful for handling expected client-side errors gracefully without tripping the circuit. ```ruby require 'circuit_breaker' class ResourceNotFoundError < StandardError; end class ValidationError < StandardError; end class ServiceUnavailableError < StandardError; end class UserService include CircuitBreaker def fetch_user(user_id) response = HTTPClient.get("https://api.example.com/users/#{user_id}") case response.status when 200 JSON.parse(response.body) when 404 raise ResourceNotFoundError, "User #{user_id} not found" when 400 raise ValidationError, "Invalid user ID" when 503 raise ServiceUnavailableError, "Service temporarily unavailable" else raise "Unexpected error: #{response.status}" end end circuit_method :fetch_user circuit_handler do |handler| handler.failure_threshold = 5 handler.failure_timeout = 10 handler.invocation_timeout = 5 # 404 and validation errors are expected - don't trip the circuit handler.excluded_exceptions = [ResourceNotFoundError, ValidationError] end end service = UserService.new # These exceptions don't increment failure count begin service.fetch_user(99999) # User doesn't exist rescue ResourceNotFoundError => e puts "Expected error: #{e.message}" puts "Circuit still closed, failures: #{service.circuit_state.failure_count}" end begin service.fetch_user("invalid") # Bad input rescue ValidationError => e puts "Expected error: #{e.message}" puts "Circuit still closed, failures: #{service.circuit_state.failure_count}" end # This exception WILL increment failure count begin service.fetch_user(123) # Service unavailable rescue ServiceUnavailableError => e puts "Service error: #{e.message}" puts "Failure count increased: #{service.circuit_state.failure_count}" end # Circuit only trips on actual service failures, not client errors ``` -------------------------------- ### Basic Circuit Breaker Implementation in Ruby Source: https://github.com/wsargent/circuit_breaker/blob/master/README.md Demonstrates how to include the CircuitBreaker mixin in a Ruby class, define a circuit method, and configure its behavior using a circuit_handler block. This includes setting failure thresholds, timeouts, and excluded exceptions. ```ruby require 'circuit_breaker' class TestService include CircuitBreaker def call_remote_service() ... circuit_method :call_remote_service # Optional circuit_handler do |handler| handler.logger = Logger.new(STDOUT) handler.failure_threshold = 5 handler.failure_timeout = 5 handler.invocation_timeout = 10 handler.excluded_exceptions = [NotConsideredFailureException] end # Optional circuit_handler_class MyCustomCircuitHandler end ``` -------------------------------- ### Configuring Circuit Handler with Count-Based Threshold in Ruby Source: https://context7.com/wsargent/circuit_breaker/llms.txt Demonstrates configuring a circuit breaker handler in Ruby with count-based failure detection. It shows how to set failure thresholds, timeouts, logging, and exclude specific exceptions from tripping the circuit. ```ruby require 'circuit_breaker' require 'logger' class WeatherService include CircuitBreaker def fetch_forecast(city) # External API call that might fail uri = URI("https://weather-api.example.com/forecast?city=#{city}") response = Net::HTTP.get_response(uri) raise "API Error" unless response.is_a?(Net::HTTPSuccess) JSON.parse(response.body) end circuit_method :fetch_forecast circuit_handler do |handler| handler.logger = Logger.new(STDOUT) # Enable debug logging handler.failure_threshold = 5 # Trip after 5 failures handler.failure_timeout = 10 # Wait 10 seconds before retry handler.invocation_timeout = 30 # Timeout if call takes > 30 seconds handler.excluded_exceptions = [NotFoundError] # Don't count these as failures end end service = WeatherService.new # Circuit starts closed - calls go through 10.times do |i| begin forecast = service.fetch_forecast("San Francisco") puts "Forecast retrieved: #{forecast}" rescue CircuitBreaker::CircuitBrokenException => e puts "Circuit is open! State: #{e.circuit_state.aasm_state}" puts "Failures: #{e.circuit_state.failure_count}" sleep 1 rescue => e puts "API call failed: #{e.message}" end end # After 5 failures, circuit opens and all calls fail immediately # After 10 seconds, circuit moves to half-open and allows one test call ``` -------------------------------- ### Basic Circuit Breaker Integration in Ruby Source: https://context7.com/wsargent/circuit_breaker/llms.txt Integrates the CircuitBreaker module into a Ruby class to protect methods. It demonstrates how to mark a method for circuit breaker protection and handle potential exceptions, including CircuitBreaker::CircuitBrokenException when the circuit is open. ```ruby require 'circuit_breaker' class PaymentService include CircuitBreaker def charge_credit_card(amount, card_number) # Simulate external API call response = HTTPClient.post("https://payment-api.example.com/charge", { amount: amount, card: card_number }) return response.body end # Protect the method with circuit breaker circuit_method :charge_credit_card end # Usage service = PaymentService.new # First few calls succeed begin result = service.charge_credit_card(100, "4111111111111111") puts "Payment successful: #{result}" rescue => e puts "Payment failed: #{e.message}" end # After multiple failures, circuit opens # CircuitBreaker::CircuitBrokenException will be raised ``` -------------------------------- ### Basic API Call with Circuit Breaker in Ruby Source: https://context7.com/wsargent/circuit_breaker/llms.txt Demonstrates making API calls within a loop, implementing a circuit breaker pattern to handle potential failures. It includes error handling, health checks after each call, and conditional logging for an open circuit state. This snippet shows the core usage for protecting external service interactions. ```ruby 10.times do |i| begin client.call_api("/data/#{i}") rescue => e puts "Call failed: #{e.message}" end # Check health after each call health = health_check(client) puts "Health: #{health[:status]}, Failures: #{health[:failure_count]}/#{health[:call_count]}" if health[:status] == :open puts "Circuit is OPEN - #{health[:time_until_retry].round(1)}s until retry" end end # Monitor circuit state for dashboards, metrics, and alerting # State information useful for debugging and observability ``` -------------------------------- ### Percentage-Based Failure Threshold Source: https://context7.com/wsargent/circuit_breaker/llms.txt Illustrates how to configure the circuit breaker to use a percentage of failures rather than a fixed count, providing more adaptive failure detection. ```APIDOC ## Percentage-Based Failure Threshold ### Description Use percentage-based failure detection instead of absolute count for more adaptive circuit breaking. This configuration ensures the circuit trips based on the proportion of failures relative to successful calls, with a minimum number of calls required before the percentage is considered. ### Method `circuit_handler do |handler| ... end` alongside `circuit_method :method_name` ### Endpoint N/A (This is a Ruby library integration, not a network endpoint) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```ruby require 'circuit_breaker' class DatabaseService include CircuitBreaker def execute_query(sql) # Simulate database query connection = Database.connect result = connection.execute(sql) connection.close return result end circuit_method :execute_query circuit_handler do |handler| handler.logger = Logger.new(STDOUT) # Trip if 50% of calls fail AND at least 10 calls have been made handler.failure_percentage_threshold = 0.5 handler.failure_percentage_minimum = 10 handler.failure_timeout = 15 handler.invocation_timeout = 5 end end db_service = DatabaseService.new # Make 20 calls, 11 succeed, 9 fail (45% failure rate) 20.times do |i| begin if i % 2 == 0 result = db_service.execute_query("SELECT * FROM users WHERE id = #{i}") puts "Query #{i} succeeded" else # Simulate failure raise "Connection timeout" end rescue CircuitBreaker::CircuitBrokenException => e puts "Circuit opened at #{e.circuit_state.call_count} calls" puts "Failure rate: #{(e.circuit_state.failure_count.to_f / e.circuit_state.call_count * 100).round(1)}%" rescue => e puts "Query #{i} failed: #{e.message}" end end # Circuit remains closed because failure rate is below 50% # If failure rate exceeds 50% after minimum calls, circuit will open ``` ### Response #### Success Response (200) Returns the successful result of the database query. #### Response Example ```json [ {"id": 0, "name": "Alice"} ] ``` #### Error Response `CircuitBreaker::CircuitBrokenException` is raised when the circuit is open. Other exceptions like `Connection timeout` may be raised by the simulated database call. #### Error Response Example ```json { "error": "Circuit is open. Please wait before retrying." } ``` ``` -------------------------------- ### Configuring Circuit Handler with Count-Based Threshold Source: https://context7.com/wsargent/circuit_breaker/llms.txt Explains how to configure the circuit breaker handler for count-based failure detection, including setting failure thresholds, timeouts, and excluding specific exceptions. ```APIDOC ## Configuring Circuit Handler with Count-Based Threshold ### Description Configure the circuit handler to customize failure thresholds, timeouts, and logging behavior using count-based failure detection. This allows for fine-tuning when the circuit trips and how long it remains open. ### Method `circuit_handler do |handler| ... end` alongside `circuit_method :method_name` ### Endpoint N/A (This is a Ruby library integration, not a network endpoint) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```ruby require 'circuit_breaker' require 'logger' class WeatherService include CircuitBreaker def fetch_forecast(city) # External API call that might fail uri = URI("https://weather-api.example.com/forecast?city=#{city}") response = Net::HTTP.get_response(uri) raise "API Error" unless response.is_a?(Net::HTTPSuccess) JSON.parse(response.body) end circuit_method :fetch_forecast circuit_handler do |handler| handler.logger = Logger.new(STDOUT) # Enable debug logging handler.failure_threshold = 5 # Trip after 5 failures handler.failure_timeout = 10 # Wait 10 seconds before retry handler.invocation_timeout = 30 # Timeout if call takes > 30 seconds handler.excluded_exceptions = [NotFoundError] # Don't count these as failures end end service = WeatherService.new # Circuit starts closed - calls go through 10.times do |i| begin forecast = service.fetch_forecast("San Francisco") puts "Forecast retrieved: #{forecast}" rescue CircuitBreaker::CircuitBrokenException => e puts "Circuit is open! State: #{e.circuit_state.aasm_state}" puts "Failures: #{e.circuit_state.failure_count}" sleep 1 rescue => e puts "API call failed: #{e.message}" end end # After 5 failures, circuit opens and all calls fail immediately # After 10 seconds, circuit moves to half-open and allows one test call ``` ### Response #### Success Response (200) Returns the successful result of the wrapped method. #### Response Example ```json { "forecast": "Sunny with a high of 75F" } ``` #### Error Response `CircuitBreaker::CircuitBrokenException` is raised when the circuit is open. Other exceptions may be raised by the wrapped method itself. #### Error Response Example ```json { "error": "Circuit is open. Please try again later." } ``` ``` -------------------------------- ### Percentage-Based Failure Threshold in Ruby Source: https://context7.com/wsargent/circuit_breaker/llms.txt Implements percentage-based failure detection for a circuit breaker in Ruby. This approach trips the circuit if a certain percentage of calls fail, given a minimum number of calls have been made. ```ruby require 'circuit_breaker' class DatabaseService include CircuitBreaker def execute_query(sql) # Simulate database query connection = Database.connect result = connection.execute(sql) connection.close return result end circuit_method :execute_query circuit_handler do |handler| handler.logger = Logger.new(STDOUT) # Trip if 50% of calls fail AND at least 10 calls have been made handler.failure_percentage_threshold = 0.5 handler.failure_percentage_minimum = 10 handler.failure_timeout = 15 handler.invocation_timeout = 5 end end db_service = DatabaseService.new # Make 20 calls, 11 succeed, 9 fail (45% failure rate) 20.times do |i| begin if i % 2 == 0 result = db_service.execute_query("SELECT * FROM users WHERE id = #{i}") puts "Query #{i} succeeded" else # Simulate failure raise "Connection timeout" end rescue CircuitBreaker::CircuitBrokenException => e puts "Circuit opened at #{e.circuit_state.call_count} calls" puts "Failure rate: #{(e.circuit_state.failure_count.to_f / e.circuit_state.call_count * 100).round(1)}%" rescue => e puts "Query #{i} failed: #{e.message}" end end # Circuit remains closed because failure rate is below 50% # If failure rate exceeds 50% after minimum calls, circuit will open ``` -------------------------------- ### Protect Multiple Methods with Shared Circuit State in Ruby Source: https://context7.com/wsargent/circuit_breaker/llms.txt This Ruby code demonstrates how to apply circuit breaker protection to several methods within a single class, ensuring they all share the same circuit breaker state. It configures failure thresholds and timeouts for the circuit. This is particularly useful when multiple methods depend on the same external service. ```ruby require 'circuit_breaker' class EmailService include CircuitBreaker def send_welcome_email(user_email) smtp_send(user_email, "Welcome!", "Thank you for signing up") end def send_notification(user_email, message) smtp_send(user_email, "Notification", message) end def verify_email_address(email) # Check if email exists via external API response = HTTPClient.get("https://email-verify.example.com/check?email=#{email}") JSON.parse(response.body)("valid") end private def smtp_send(to, subject, body) # SMTP sending logic Net::SMTP.start('smtp.example.com', 25) do |smtp| message = "From: noreply@example.com\nTo: #{to}\nSubject: #{subject}\n\n#{body}" smtp.send_message(message, 'noreply@example.com', to) end end # Protect all public email methods with the same circuit circuit_method :send_welcome_email, :send_notification, :verify_email_address circuit_handler do |handler| handler.failure_threshold = 3 handler.failure_timeout = 20 handler.invocation_timeout = 10 end end email_service = EmailService.new # All three methods share the same circuit state begin email_service.send_welcome_email("user@example.com") email_service.verify_email_address("user@example.com") email_service.send_notification("user@example.com", "Your order shipped!") rescue CircuitBreaker::CircuitBrokenException => e puts "Email circuit is open - all email operations blocked" puts "Circuit state: #{email_service.circuit_state.aasm_state}" end # If any method fails 3 times, ALL email methods will be blocked # This is useful when all methods depend on the same external service ``` -------------------------------- ### Configure Invocation Timeouts in Ruby Source: https://context7.com/wsargent/circuit_breaker/llms.txt This snippet demonstrates how to configure invocation timeouts for a circuit breaker in Ruby. It prevents hung calls from blocking indefinitely and trips the circuit on slow responses. The configuration includes setting failure thresholds, failure timeouts, and specific invocation timeouts. ```ruby require 'circuit_breaker' class ReportService include CircuitBreaker def generate_monthly_report(user_id) # Complex report generation that might hang data = Database.query("SELECT * FROM transactions WHERE user_id = ?", user_id) # Process large dataset report = data.map do |transaction| calculate_metrics(transaction) end # Send to PDF generator (external service) HTTPClient.post("https://pdf-service.example.com/generate", report: report) end circuit_method :generate_monthly_report circuit_handler do |handler| handler.logger = Logger.new(STDOUT) handler.failure_threshold = 3 handler.failure_timeout = 30 # If report generation takes longer than 15 seconds, timeout and trip circuit handler.invocation_timeout = 15 end end service = ReportService.new start_time = Time.now begin report = service.generate_monthly_report(12345) puts "Report generated successfully in #{Time.now - start_time} seconds" rescue CircuitBreaker::CircuitBrokenException => e elapsed = Time.now - start_time if elapsed < 1 # Circuit was already open puts "Circuit is open - request failed immediately" puts "State: #{e.circuit_state.aasm_state}" else # Timeout occurred puts "Report generation timed out after #{elapsed.round(2)} seconds" puts "Invocation timeout exceeded, failure count: #{service.circuit_state.failure_count}" end end # Timeouts count as failures and will trip the circuit # Prevents slow services from consuming resources ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.