gobreaker

repository·master·Indexed 25 days ago

https://github.com/sony/gobreaker

A Go implementation of the Circuit Breaker pattern designed to protect resources and improve resilience by preventing repeated attempts of operations likely to fail. It supports three states (StateClosed, StateHalfOpen, StateOpen), configurable trip logic via a Settings struct, and a DistributedCircuitBreaker for synchronizing state across nodes using a SharedDataStore, with a provided Redis implementation.

Tokens
3.6K
Snippets
10
Records
31
Agent score
86%

What's inside gobreaker

  1. Configure CircuitBreaker Settings

    master

    The Settings struct allows you to fine-tune the state machine behavior:

    • Name: The name of the CircuitBreaker.
    • MaxRequests: Maximum number of requests allowed to pass through when the state is half-open. If 0, only 1 request is allowed.
    • Interval: Cyclic period of the closed state to clear internal Counts. If 0, counts are never cleared during the closed state.
    • BucketPeriod: Duration for each bucket in the rolling window strategy. If ≤ 0, a fixed window strategy is used instead. Interval is automatically adjusted to a multiple of BucketPeriod.
    • Timeout: Period of the open state before transitioning to half-open. If 0, defaults to 60 seconds.
    • ReadyToTrip: Function called with a copy of Counts when a request fails in the closed state. If it returns true, the breaker trips to open. Default: trips after 5 consecutive failures.
    • OnStateChange: Callback triggered whenever the state changes.
    • IsSuccessful: Function to determine if an error counts as a success. If nil, all non-nil errors are failures.
    • IsExcluded: Function to determine if an error should be ignored for metrics (e.g., context cancellations). If true, the request is neither a success nor a failure.
  2. Example: Wrapping an HTTP GET request

    master

    This example demonstrates how to wrap an HTTP request using a CircuitBreaker that returns []byte.

    var cb *gobreaker.CircuitBreaker[[]byte]
    
    func Get(url string) ([]byte, error) {
    	body, err := cb.Execute(func() ([]byte, error) {
    		resp, err := http.Get(url)
    		if err != nil {
    			return nil, err
    		}
    
    		defer resp.Body.Close()
    		return io.ReadAll(resp.Body)
    	})
    	if err != nil {
    		return nil, err
    	}
    
    	return body, nil
    }
  3. Initialize a new CircuitBreaker

    master
    Use NewCircuitBreaker[T] to create a new instance. The type parameter T specifies the return type of the requests being wrapped. You must provide a Settings struct to configure the behavior.
  4. Execute requests with CircuitBreaker.Execute

    master

    Wrap your request logic in the Execute method. Execute accepts a function func() (T, error).

    • If the breaker is open/rejecting, Execute returns an error immediately.
    • If accepted, it runs the function and returns the result.
    • If the wrapped function panics, gobreaker catches the panic, treats it as an error for the state machine, and then re-panics.
  5. Configure a CircuitBreaker using Settings

    master

    To create a new CircuitBreaker, use the NewCircuitBreaker function and provide a Settings struct. The Settings allow you to define the breaker's behavior, including how it trips, how it handles successes/failures, and how it transitions between states.

    Settings Fields

    • Name: The identifier for the breaker.
    • MaxRequests: Maximum requests allowed in StateHalfOpen. If 0, it defaults to 1.
    • Interval: The cyclic period for clearing internal counts in StateClosed. If ≤ 0, counts are not cleared.
    • BucketPeriod: Defines the duration for each bucket in a rolling window. If ≤ 0, a fixed window strategy is used.
    • Timeout: The duration the breaker stays in StateOpen before transitioning to StateHalfOpen. If ≤ 0, defaults to 60s.
    • ReadyToTrip: A function called when a request fails in StateClosed. If it returns true, the breaker trips to StateOpen. Default: trips after 5 consecutive failures.
    • OnStateChange: A callback triggered whenever the state changes.
    • IsSuccessful: A function to determine if an error counts as a success. Default: err == nil is a success.
    • IsExcluded: A function to determine if an error should be ignored entirely (not counted as success or failure). Default: no errors are excluded.
  6. Understand CircuitBreaker Counts

    master

    The Counts struct tracks the metrics used by the state machine. These counts are cleared upon state changes or at Interval boundaries:

    • Requests: Total requests.
    • TotalSuccesses: Total successful requests.
    • TotalFailures: Total failed requests.
    • TotalExclusions: Total requests ignored via IsExcluded.
    • ConsecutiveSuccesses: Number of consecutive successes.
    • ConsecutiveFailures: Number of consecutive failures.
  7. Check CircuitBreaker state and counts

    master

    You can inspect the current status of a CircuitBreaker using the State() and Counts() methods.

    • State(): Returns the current State (StateClosed, StateHalfOpen, or StateOpen).
    • Counts(): Returns the current internal Counts (successes, failures, etc.).
  8. TwoStepCircuitBreaker State and Counts

    master

    The TwoStepCircuitBreaker[T] provides access to the underlying CircuitBreaker metrics and status through the following methods:

    • Name() string: Returns the name of the circuit breaker.
    • State() State: Returns the current state (e.g., Closed, Open, HalfOpen).
    • Counts() Counts: Returns the internal counters (successes, failures, etc.).
  9. Implement the SharedDataStore interface

    master

    To use a DistributedCircuitBreaker, you must provide an implementation of the SharedDataStore interface. This interface is responsible for managing distributed locks and persisting the circuit breaker's state across multiple instances using a shared backend (e.g., Redis).

    type SharedDataStore interface {
    	Lock(name string) error
    	Unlock(name string) error
    	GetData(name string) ([]byte, error)
    	SetData(name string, data []byte) error
    }
  10. Use TwoStepCircuitBreaker for granular request control

    master
    The TwoStepCircuitBreaker[T] allows you to decouple the decision to proceed with a request from the reporting of the request's outcome. Instead of wrapping a function, you call Allow() to check if a request is permitted. If permitted, Allow() returns a done callback function. You must call this done(err) callback after your operation completes, passing the resulting error (or nil if successful), to update the breaker's internal state.