Documentation
¶
Overview ¶
Package resilience provides circuit breaker and provider failover primitives.
The central type is CircuitBreaker, a classic three-state breaker (closed → open → half-open) that protects callers from cascading failures. FallbackGroup composes multiple instances of any provider type with per-entry circuit breakers so that a failing primary is automatically bypassed in favour of healthy fallbacks.
All types are safe for concurrent use.
Index ¶
- Variables
- func ExecuteWithResult[T any, R any](fg *FallbackGroup[T], fn func(T) (R, error)) (R, error)
- type CircuitBreaker
- type CircuitBreakerConfig
- type FallbackConfig
- type FallbackGroup
- type LLMFallback
- func (f *LLMFallback) AddFallback(name string, provider llm.Provider)
- func (f *LLMFallback) Capabilities() llm.ModelCapabilities
- func (f *LLMFallback) Complete(ctx context.Context, req llm.CompletionRequest) (*llm.CompletionResponse, error)
- func (f *LLMFallback) CountTokens(messages []llm.Message) (int, error)
- func (f *LLMFallback) StreamCompletion(ctx context.Context, req llm.CompletionRequest) (<-chan llm.Chunk, error)
- type STTFallback
- type State
- type TTSFallback
- func (f *TTSFallback) AddFallback(name string, provider tts.Provider)
- func (f *TTSFallback) CloneVoice(ctx context.Context, samples [][]byte) (*tts.VoiceProfile, error)
- func (f *TTSFallback) ListVoices(ctx context.Context) ([]tts.VoiceProfile, error)
- func (f *TTSFallback) SynthesizeStream(ctx context.Context, text <-chan string, voice tts.VoiceProfile) (<-chan []byte, error)
Constants ¶
This section is empty.
Variables ¶
var ErrAllFailed = errors.New("all providers failed")
ErrAllFailed is returned when every entry in a FallbackGroup fails or has an open circuit breaker.
var ErrCircuitOpen = errors.New("circuit breaker is open")
ErrCircuitOpen is returned by CircuitBreaker.Execute when the breaker is in the open state and the reset timeout has not yet elapsed.
Functions ¶
func ExecuteWithResult ¶
func ExecuteWithResult[T any, R any](fg *FallbackGroup[T], fn func(T) (R, error)) (R, error)
ExecuteWithResult tries fn against each entry in the group until one succeeds, returning both the result value and error. This is a package-level function because Go does not support method-level type parameters.
Types ¶
type CircuitBreaker ¶
type CircuitBreaker struct {
// contains filtered or unexported fields
}
CircuitBreaker implements the three-state circuit breaker pattern. It is safe for concurrent use from multiple goroutines.
func NewCircuitBreaker ¶
func NewCircuitBreaker(cfg CircuitBreakerConfig) *CircuitBreaker
NewCircuitBreaker creates a CircuitBreaker with the supplied configuration. Zero-value config fields are replaced with sensible defaults.
func (*CircuitBreaker) Execute ¶
func (cb *CircuitBreaker) Execute(fn func() error) error
Execute runs fn if the breaker allows it. In the open state it returns ErrCircuitOpen without calling fn. In the half-open state a limited number of probe calls are permitted.
func (*CircuitBreaker) Reset ¶
func (cb *CircuitBreaker) Reset()
Reset manually forces the breaker back to StateClosed, clearing all failure counters.
func (*CircuitBreaker) State ¶
func (cb *CircuitBreaker) State() State
State returns the current State of the breaker. If the breaker is open and the reset timeout has elapsed, the returned state is StateHalfOpen (the actual transition happens on the next [Execute] call).
type CircuitBreakerConfig ¶
type CircuitBreakerConfig struct {
// Name is a human-readable label used in log messages.
Name string
// MaxFailures is the number of consecutive failures in the closed state
// before the breaker opens. Default: 5.
MaxFailures int
// ResetTimeout is how long the breaker stays open before transitioning to
// half-open. Default: 30s.
ResetTimeout time.Duration
// HalfOpenMax is the maximum number of probe calls allowed in the half-open
// state before the breaker decides whether to close or re-open. Default: 3.
HalfOpenMax int
}
CircuitBreakerConfig holds tuning knobs for a CircuitBreaker.
type FallbackConfig ¶
type FallbackConfig struct {
CircuitBreaker CircuitBreakerConfig
}
FallbackConfig configures the per-entry circuit breaker created for each provider in a FallbackGroup.
type FallbackGroup ¶
type FallbackGroup[T any] struct { // contains filtered or unexported fields }
FallbackGroup wraps a primary and zero or more fallback instances of the same provider type. When the primary fails (or its circuit breaker is open), the next healthy fallback is tried in registration order.
FallbackGroup.Execute and ExecuteWithResult are safe for concurrent use. FallbackGroup.AddFallback must be called during initialisation, before any concurrent Execute calls — it is NOT safe to call concurrently with Execute.
func NewFallbackGroup ¶
func NewFallbackGroup[T any](primary T, primaryName string, cfg FallbackConfig) *FallbackGroup[T]
NewFallbackGroup creates a FallbackGroup with primary as the first entry. Additional fallbacks are registered via FallbackGroup.AddFallback.
func (*FallbackGroup[T]) AddFallback ¶
func (fg *FallbackGroup[T]) AddFallback(name string, fallback T)
AddFallback appends a fallback provider. Fallbacks are tried in the order they are added, after the primary.
AddFallback must only be called during initialisation, before any concurrent calls to FallbackGroup.Execute or ExecuteWithResult.
func (*FallbackGroup[T]) Execute ¶
func (fg *FallbackGroup[T]) Execute(fn func(T) error) error
Execute tries fn against each entry in order until one succeeds. Circuit-breaker-open entries are skipped. Returns ErrAllFailed wrapped with the last error if every entry fails.
type LLMFallback ¶
type LLMFallback struct {
// contains filtered or unexported fields
}
LLMFallback implements llm.Provider with automatic failover across multiple LLM backends. Each backend has its own circuit breaker; when the primary fails or its breaker is open, the next healthy fallback is tried.
func NewLLMFallback ¶
func NewLLMFallback(primary llm.Provider, primaryName string, cfg FallbackConfig) *LLMFallback
NewLLMFallback creates an LLMFallback with primary as the preferred backend.
func (*LLMFallback) AddFallback ¶
func (f *LLMFallback) AddFallback(name string, provider llm.Provider)
AddFallback registers an additional LLM provider as a fallback.
func (*LLMFallback) Capabilities ¶
func (f *LLMFallback) Capabilities() llm.ModelCapabilities
Capabilities returns the capabilities of the first entry (the primary). This does not participate in failover because capabilities are static metadata.
func (*LLMFallback) Complete ¶
func (f *LLMFallback) Complete(ctx context.Context, req llm.CompletionRequest) (*llm.CompletionResponse, error)
Complete sends the request to the first healthy provider and returns its response. If the primary fails, subsequent fallbacks are tried.
func (*LLMFallback) CountTokens ¶
func (f *LLMFallback) CountTokens(messages []llm.Message) (int, error)
CountTokens delegates to the first healthy provider's token counter.
func (*LLMFallback) StreamCompletion ¶
func (f *LLMFallback) StreamCompletion(ctx context.Context, req llm.CompletionRequest) (<-chan llm.Chunk, error)
StreamCompletion sends the request to the first healthy provider and returns a streaming chunk channel. Note: only the initial connection attempt is covered by failover; once a stream is established, mid-stream errors are the caller's responsibility.
type STTFallback ¶
type STTFallback struct {
// contains filtered or unexported fields
}
STTFallback implements stt.Provider with automatic failover across multiple STT backends. Each backend has its own circuit breaker.
func NewSTTFallback ¶
func NewSTTFallback(primary stt.Provider, primaryName string, cfg FallbackConfig) *STTFallback
NewSTTFallback creates an STTFallback with primary as the preferred backend.
func (*STTFallback) AddFallback ¶
func (f *STTFallback) AddFallback(name string, provider stt.Provider)
AddFallback registers an additional STT provider as a fallback.
func (*STTFallback) StartStream ¶
func (f *STTFallback) StartStream(ctx context.Context, cfg stt.StreamConfig) (stt.SessionHandle, error)
StartStream opens a streaming transcription session against the first healthy provider. If the primary fails to start the stream, subsequent fallbacks are tried.
type State ¶
type State int
State represents the current operating mode of a CircuitBreaker.
const ( // StateClosed is the normal operating state — all calls are forwarded. StateClosed State = iota // StateOpen indicates the breaker has tripped due to consecutive failures. // Calls are rejected immediately with [ErrCircuitOpen] until the reset // timeout elapses. StateOpen // StateHalfOpen is the probe state entered after the reset timeout. A limited // number of calls are allowed through; if they succeed the breaker closes, // otherwise it re-opens. StateHalfOpen )
type TTSFallback ¶
type TTSFallback struct {
// contains filtered or unexported fields
}
TTSFallback implements tts.Provider with automatic failover across multiple TTS backends. Each backend has its own circuit breaker.
func NewTTSFallback ¶
func NewTTSFallback(primary tts.Provider, primaryName string, cfg FallbackConfig) *TTSFallback
NewTTSFallback creates a TTSFallback with primary as the preferred backend.
func (*TTSFallback) AddFallback ¶
func (f *TTSFallback) AddFallback(name string, provider tts.Provider)
AddFallback registers an additional TTS provider as a fallback.
func (*TTSFallback) CloneVoice ¶
func (f *TTSFallback) CloneVoice(ctx context.Context, samples [][]byte) (*tts.VoiceProfile, error)
CloneVoice creates a new voice profile using the first healthy provider.
func (*TTSFallback) ListVoices ¶
func (f *TTSFallback) ListVoices(ctx context.Context) ([]tts.VoiceProfile, error)
ListVoices returns available voices from the first healthy provider.
func (*TTSFallback) SynthesizeStream ¶
func (f *TTSFallback) SynthesizeStream(ctx context.Context, text <-chan string, voice tts.VoiceProfile) (<-chan []byte, error)
SynthesizeStream consumes text fragments and returns a channel of audio bytes, trying the first healthy provider. Only the initial stream setup is covered by failover; mid-stream errors are the caller's responsibility.