executor

package
v1.1.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 8, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrCircuitOpen = fmt.Errorf("circuit breaker is open")

ErrCircuitOpen is returned when a call is rejected because the circuit is open.

Functions

func ToString

func ToString(cmd *exec.Cmd) string

Types

type CircuitBreakerConfig

type CircuitBreakerConfig struct {
	FailureThreshold int           // Number of consecutive failures to trip the breaker
	RecoveryTimeout  time.Duration // Time to wait before probing in HALF-OPEN
	// IsFailure classifies whether a command result counts as a circuit breaker failure.
	// Receives the command class, combined output (nil for Run calls), and the error.
	// If nil, any non-nil error is treated as a failure (default behavior).
	IsFailure func(commandClass string, output []byte, err error) bool
}

CircuitBreakerConfig holds configuration for a circuit breaker.

func DefaultCircuitBreakerConfig

func DefaultCircuitBreakerConfig() CircuitBreakerConfig

DefaultCircuitBreakerConfig returns the default configuration.

type CircuitBreakerExecutor

type CircuitBreakerExecutor struct {
	// contains filtered or unexported fields
}

CircuitBreakerExecutor wraps an Executor with per-command-class circuit breakers.

func NewCircuitBreakerExecutor

func NewCircuitBreakerExecutor(delegate Executor, config CircuitBreakerConfig) *CircuitBreakerExecutor

NewCircuitBreakerExecutor creates a new CircuitBreakerExecutor wrapping the delegate.

func NewCircuitBreakerExecutorWithClock

func NewCircuitBreakerExecutorWithClock(delegate Executor, config CircuitBreakerConfig, clock Clock) *CircuitBreakerExecutor

NewCircuitBreakerExecutorWithClock creates a CircuitBreakerExecutor with an injectable clock (for testing).

func (*CircuitBreakerExecutor) AllBreakers

AllBreakers returns a snapshot of all circuit breakers for observability.

func (*CircuitBreakerExecutor) CombinedOutput

func (e *CircuitBreakerExecutor) CombinedOutput(cmd *exec.Cmd) ([]byte, error)

CombinedOutput executes the command and returns its combined stdout+stderr through the circuit breaker. Returns ErrCircuitOpen if the breaker for this command class is open.

func (*CircuitBreakerExecutor) Output

func (e *CircuitBreakerExecutor) Output(cmd *exec.Cmd) ([]byte, error)

Output executes the command and returns its output through the circuit breaker. Returns ErrCircuitOpen if the breaker for this command class is open.

func (*CircuitBreakerExecutor) Reset added in v1.1.0

func (e *CircuitBreakerExecutor) Reset()

Reset resets all circuit breakers in this executor to closed state. Call after successfully recovering an external dependency (e.g. tmux server restart).

func (*CircuitBreakerExecutor) Run

func (e *CircuitBreakerExecutor) Run(cmd *exec.Cmd) error

Run executes the command through the circuit breaker, delegating to the wrapped executor. Returns ErrCircuitOpen if the breaker for this command class is open.

type CircuitBreakerRegistry

type CircuitBreakerRegistry struct {
	// contains filtered or unexported fields
}

CircuitBreakerRegistry maintains a global registry of all CircuitBreakerExecutor instances. This enables the debug endpoint to aggregate circuit breaker state from all sessions.

func GetGlobalRegistry

func GetGlobalRegistry() *CircuitBreakerRegistry

GetGlobalRegistry returns the global circuit breaker registry.

func (*CircuitBreakerRegistry) AllBreakers

AllBreakers returns a combined snapshot of all circuit breakers across all registered executors. The returned map keys are prefixed with the executor key for disambiguation (e.g., "git-session1/git-diff").

func (*CircuitBreakerRegistry) Register

func (r *CircuitBreakerRegistry) Register(key string, cbe *CircuitBreakerExecutor)

Register adds a CircuitBreakerExecutor to the registry with a unique key. The key should identify the owner (e.g., "git-<session-title>" or "tmux-<session-title>").

func (*CircuitBreakerRegistry) ResetAll added in v1.1.0

func (r *CircuitBreakerRegistry) ResetAll()

ResetAll resets all circuit breakers in all registered executors to closed state. Call after successfully recovering an external dependency (e.g. tmux server restart).

func (*CircuitBreakerRegistry) Unregister

func (r *CircuitBreakerRegistry) Unregister(key string)

Unregister removes a CircuitBreakerExecutor from the registry.

type CircuitBreakerSnapshot

type CircuitBreakerSnapshot struct {
	State               CircuitState
	ConsecutiveFailures int
	LastStateChange     time.Time
	Config              CircuitBreakerConfig
}

CircuitBreakerSnapshot holds a point-in-time view of a circuit breaker's state.

type CircuitState

type CircuitState int

CircuitState represents the current state of a circuit breaker.

const (
	CircuitClosed   CircuitState = iota // Normal operation
	CircuitOpen                         // Fail-fast mode
	CircuitHalfOpen                     // Probing for recovery
)

func (CircuitState) String

func (s CircuitState) String() string

type Clock

type Clock interface {
	Now() time.Time
}

Clock is an interface for time operations (injectable for testing).

type Exec

type Exec struct{}

func (Exec) CombinedOutput

func (e Exec) CombinedOutput(cmd *exec.Cmd) ([]byte, error)

func (Exec) Output

func (e Exec) Output(cmd *exec.Cmd) ([]byte, error)

func (Exec) Run

func (e Exec) Run(cmd *exec.Cmd) error

type Executor

type Executor interface {
	Run(cmd *exec.Cmd) error
	Output(cmd *exec.Cmd) ([]byte, error)
	CombinedOutput(cmd *exec.Cmd) ([]byte, error)
}

func MakeExecutor

func MakeExecutor() Executor

func MakeTimeoutExecutor

func MakeTimeoutExecutor(timeout time.Duration) Executor

MakeTimeoutExecutor creates an executor with timeout protection. This prevents commands from hanging indefinitely, which is critical for preventing test hangs and production issues with external commands.

type Resettable added in v1.1.0

type Resettable interface {
	Reset()
}

Resettable is implemented by executors that support resetting their internal failure state (e.g., after a successful recovery from a dependency outage). Use a type assertion to this interface rather than asserting to *CircuitBreakerExecutor directly, so that mock or wrapper executors can also participate in resets.

type TimeoutExecutor

type TimeoutExecutor struct {
	// contains filtered or unexported fields
}

TimeoutExecutor wraps command execution with context-based timeouts to prevent indefinite blocking. This is critical for preventing hangs on external commands like 'which claude' or tmux operations.

func NewTimeoutExecutor

func NewTimeoutExecutor(timeout time.Duration) *TimeoutExecutor

NewTimeoutExecutor creates a new timeout-aware executor with the specified timeout duration. The timeout applies to each individual command execution.

func (*TimeoutExecutor) CombinedOutput

func (e *TimeoutExecutor) CombinedOutput(cmd *exec.Cmd) ([]byte, error)

CombinedOutput executes the command and returns combined stdout+stderr with timeout protection.

func (*TimeoutExecutor) Output

func (e *TimeoutExecutor) Output(cmd *exec.Cmd) ([]byte, error)

Output executes the command and returns its output with timeout protection. If the command does not complete within the timeout duration, it is killed and an error is returned.

func (*TimeoutExecutor) OutputWithPipes

func (e *TimeoutExecutor) OutputWithPipes(cmd *exec.Cmd) ([]byte, error)

OutputWithPipes is a better implementation of Output that properly captures stdout/stderr This should be used when you need reliable output capture with timeout

func (*TimeoutExecutor) Run

func (e *TimeoutExecutor) Run(cmd *exec.Cmd) error

Run executes the command with timeout protection. If the command does not complete within the timeout duration, it is killed and an error is returned.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL