Skip to content

Tripwire is a Go-based circuit breaker that provides lightweight protection for high-traffic systems. It intelligently preemptively handles failures and ensures stability by automatically disconnecting based on threshold conditions.

License

Notifications You must be signed in to change notification settings

shengyanli1982/tripwire

Repository files navigation

English | 中文

logo

Go Report Card Build Status Go Reference

What is Circuit Breaker?

In a distributed system, a single service failure can lead to a cascade of failures, causing the entire system to fail. Circuit breakers are designed to prevent this from happening by proactively disconnecting services that are likely to fail. This ensures system stability and allows it to continue functioning even when individual services are experiencing issues.

What is tripwire?

tripwire is a lightweight circuit breaker library written in Go. It is designed to protect high-traffic systems by intelligently preempting failures and ensuring stability through automatic threshold-based disconnections. tripwire aims to be simple, easy to use, and highly configurable, making it effortless for developers to integrate into their existing systems.

Why tripwire?

While there are already many circuit breaker projects available on GitHub, tripwire stands out by providing a powerful yet user-friendly circuit breaker solution. Inspired by Google's circuit breaker designs, tripwire offers a robust circuit breaker that is easy to understand and seamlessly integrate into any system.

Designed to be simple, easy to use, and highly configurable, tripwire allows developers to effortlessly integrate it into their existing systems. It follows Google's SRE (Site Reliability Engineering) principles, automatically disconnecting failing services and reconnecting them when they become healthy. It also includes a self-adaptive mechanism to adjust the threshold based on the failure rate.

But why do we need another circuit breaker project? While there are already many circuit breaker projects available on GitHub, they often fall into two categories: either too complex to understand or too simple to be practical. tripwire bridges this gap by providing a powerful yet user-friendly circuit breaker solution.

Features

The tripwire library offers the following features:

  1. RingBuffer for storing state values.
  2. Sliding Window for calculating state values.
  3. Self-Adapter for dynamically adjusting the threshold based on the failure rate.
  4. Retry for automatically retrying failed requests.
  5. Circuit Breaker for disconnecting services.

Installation

go get github.com/shengyanli1982/tripwire

Quick Start

Getting started with tripwire is simple. Just a few lines of code are needed.

1. Configuration

tripwire provides a config object that allows you to register the circuit breaker and retry modules. The config object has the following fields:

  • WithBreaker: Use a circuit breaker module that implements the Breaker interface. The default is GoogleBreaker.
  • WithRetry: Use a retry module that implements the Retry interface. The default is emptyRetryResult.

Tip

If you want to use a custom circuit breaker or retry module, you can implement the specific internal interface and pass it to the config object.

Breaker Interface:

// Breaker 接口定义了熔断器的主要操作
// The Breaker interface defines the main operations of the circuit breaker
type Breaker = interface {
	// Allow 方法用于检查是否允许新的操作
	// The Allow method is used to check whether new operations are allowed
	Allow() (Notifier, error)

	// Do 方法执行一个操作,并处理熔断逻辑
	// The Do method executes an operation and handles the circuit breaking logic
	Do(fn HandleFunc) error

	// DoWithAcceptable 方法执行一个操作,并处理熔断逻辑和可接受性检查
	// The DoWithAcceptable method executes an operation and handles the circuit breaking logic and acceptability check
	DoWithAcceptable(fn HandleFunc, acceptable AcceptableFunc) error

	// DoWithFallback 方法执行一个操作,并处理熔断逻辑和失败回退
	// The DoWithFallback method executes an operation and handles the circuit breaking logic and failure fallback
	DoWithFallback(fn HandleFunc, fallback FallbackFunc) error

	// DoWithFallbackAcceptable 方法执行一个操作,并处理熔断逻辑、失败回退和可接受性检查
	// The DoWithFallbackAcceptable method executes an operation and handles the circuit breaking logic, failure fallback and acceptability check
	DoWithFallbackAcceptable(fn HandleFunc, fallback FallbackFunc, acceptable AcceptableFunc) error

	// Stop 方法停止熔断器的运行
	// The Stop method stops the operation of the circuit breaker
	Stop()
}

Retry Interface:

// Retry 接口定义了重试操作的主要方法
// The Retry interface defines the main methods for retry operations
type Retry = interface {
	// TryOnConflictVal 方法尝试执行一个操作,并在冲突时进行重试
	// The TryOnConflictVal method tries to execute an operation and retries in case of conflict
	TryOnConflictVal(fn RetryableFunc) RetryResult
}

// RetryResult 接口定义了重试操作的结果
// The RetryResult interface defines the result of a retry operation
type RetryResult = interface {
	// Data 方法返回操作的结果数据
	// The Data method returns the result data of the operation
	Data() any

	// TryError 方法返回尝试操作时的错误
	// The TryError method returns the error when trying the operation
	TryError() error

	// ExecErrors 方法返回所有执行操作时的错误
	// The ExecErrors method returns all errors when executing the operation
	ExecErrors() []error

	// IsSuccess 方法返回操作是否成功
	// The IsSuccess method returns whether the operation is successful
	IsSuccess() bool

	// LastExecError 方法返回最后一次执行操作时的错误
	// The LastExecError method returns the error of the last execution of the operation
	LastExecError() error

	// FirstExecError 方法返回第一次执行操作时的错误
	// The FirstExecError method returns the error of the first execution of the operation
	FirstExecError() error

	// ExecErrorByIndex 方法返回指定索引处执行操作时的错误
	// The ExecErrorByIndex method returns the error when executing the operation at the specified index
	ExecErrorByIndex(idx int) error

	// Count 方法返回操作的执行次数
	// The Count method returns the number of executions of the operation
	Count() int64
}

2. Components

The tripwire library consists of the following components:

2.1. GoogleBreaker

The GoogleBreaker is a circuit breaker module that implements the Breaker interface. It is based on Google's SRE principles and is designed to protect high-traffic systems by proactively disconnecting failing services and reconnecting them when they become healthy.

2.1.1. Config

Google Breaker algorithm formula:

gb

  • K: Adjusts thresholds or weights in the fuse decision algorithm, affecting its sensitivity.
  • Protected: Specifies the amount of resources to be protected after the fuse is opened.

The circuit breaker operates based on the formula mentioned in the code.

  • Under normal conditions, when the number of requests and accepts are equal, there is no rejection, and the circuit breaker is not triggered.
  • As the number of accepts decreases, the probability of rejection increases. When the probability exceeds 0, the circuit breaker is triggered. If the number of accepts reaches 0, the circuit breaker is completely open.
  • When the service becomes healthy again, the number of requests and accepts will increase. However, due to the faster increase of K * accepts, the probability of rejection quickly returns to 0, effectively closing the circuit breaker.

As usual: k = 1.5, protected = 5, stateWindow = 10s

  • WithCallback: Set the callback object. The default value is DefaultConfig.
  • WithK: Set the k value of the configuration. The default value is DefaultKValue.
  • WithProtected: Set the protected value of the configuration. The default value is DefaultProtected.
  • WithStateWindow: Set the state window of the configuration. The default value is DefaultStateWindow.

2.1.2. Methods

The GoogleBreaker module provides the following methods:

  • NewGoogleBreaker: Create a new google breaker object.
  • Stop: Stop the google breaker operation.
  • DoWithFallbackAcceptable: Execute a function with fallback and acceptable functions.
  • DoWithFallback: Execute a function with a fallback function.
  • DoWithAcceptable: Execute a function with an acceptable function.
  • Do: Execute a function.

3. Methods

The tripwire library provides the following methods:

  • New: Create a new tripwire object.
  • Stop: Stop the circuit breaker operation.
  • DoWithFallbackAcceptable: Execute a function with fallback and acceptable functions.
  • DoWithFallback: Execute a function with a fallback function.
  • DoWithAcceptable: Execute a function with an acceptable function.
  • Do: Execute a function.
  • Allow: Check if the circuit breaker allows the execution. (Note: This method is pure manual and not recommended)

4. Examples

Example code is located in the examples directory.

4.1 Simple

Here is a simple example of using the tripwire library to create a circuit breaker with just a few lines of code.

package main

import (
	"errors"
	"fmt"

	tp "github.com/shengyanli1982/tripwire"
	cb "github.com/shengyanli1982/tripwire/circuitbreaker"
)

// 定义一个全局错误变量:执行错误
// Define a global error variable: execution error
var executionError = errors.New("execution error")

// main 函数是程序的入口点
// The main function is the entry point of the program
func main() {
	// 创建一个新的断路器配置
	// Create a new circuit breaker configuration
	config := cb.NewConfig()

	// 创建一个新的断路器,使用 Google 断路器和给定的配置
	// Create a new circuit breaker, using a Google circuit breaker and the given configuration
	breaker := tp.New(tp.NewConfig().WithBreaker(cb.NewGoogleBreaker(config)))

	// 在 main 函数结束时停止断路器
	// Stop the circuit breaker when the main function ends
	defer breaker.Stop()

	// 循环 50 次
	// Loop 50 times
	for i := 0; i < 50; i++ {
		// 使用断路器执行一个函数
		// Use the circuit breaker to execute a function
		err := breaker.Do(func() error {
			// 如果 i 是偶数,则返回执行错误
			// If i is even, return the execution error
			if i%2 == 0 {
				return executionError
			}

			// 否则返回 nil
			// Otherwise return nil
			return nil
		})

		// 如果执行函数返回了错误,则打印错误
		// If the execution function returned an error, print the error
		if err != nil {
			fmt.Printf("# Unexpected error: %v\n", err)
		}
	}
}

Result

When running the code, the output will include the message "service unavailable" when the circuit breaker is triggered.

$ go run demo.go
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: service unavailable
# Unexpected error: execution error
# Unexpected error: service unavailable
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: execution error
# Unexpected error: service unavailable
# Unexpected error: service unavailable
# Unexpected error: service unavailable
# Unexpected error: service unavailable
# Unexpected error: service unavailable
# Unexpected error: execution error
# Unexpected error: service unavailable
# Unexpected error: service unavailable

4.2 No Retry

Here is an example of using the tripwire library without the retry module to create a circuit breaker with some cases. The code snippet is quite large, please be patient.

package main

import (
	"errors"
	"fmt"
	"time"

	tp "github.com/shengyanli1982/tripwire"
	cb "github.com/shengyanli1982/tripwire/circuitbreaker"
)

// 定义两个全局错误变量:执行错误和回退错误
// Define two global error variables: execution error and fallback error
var (
	// executionError 是当执行函数时发生的错误
	// executionError is the error that occurs when executing the function
	executionError = errors.New("execution error")

	// fallbackError 是当执行回退函数时发生的错误
	// fallbackError is the error that occurs when executing the fallback function
	fallbackError = errors.New("fallback error")
)

// demoCallback 结构体实现了回调接口
// The demoCallback struct implements the callback interface
type demoCallback struct{}

// OnSuccess 方法在成功执行函数时被调用,打印一个消息和可选的错误
// The OnSuccess method is called when the function is successfully executed, printing a message and an optional error
func (d *demoCallback) OnSuccess(err error) {
	fmt.Printf("OnSuccess: %v\n", err)
}

// OnFailure 方法在执行函数失败时被调用,打印一个消息和失败的原因
// The OnFailure method is called when the function execution fails, printing a message and the reason for the failure
func (d *demoCallback) OnFailure(err, reason error) {
	fmt.Printf("OnFailure: %v, %v\n", err, reason)
}

// OnAccept 方法在接受错误时被调用,打印一个消息、熔断比例和失败比例
// The OnAccept method is called when an error is accepted, printing a message, the fuse ratio, and the failure ratio
func (d *demoCallback) OnAccept(reason error, fuse, failure float64) {
	fmt.Printf("OnAccept: %v, fuse ratio: %v, failure ratio %v\n", reason, fuse, failure)
}

func main() {
	// 创建一个新的断路器配置,并设置回调函数
	// Create a new circuit breaker configuration and set the callback function
	config := cb.NewConfig().WithCallback(&demoCallback{})

	// 创建一个新的断路器,使用 Google 断路器和给定的配置
	// Create a new circuit breaker, using a Google circuit breaker and the given configuration
	breaker := tp.New(tp.NewConfig().WithBreaker(cb.NewGoogleBreaker(config)))

	// 在 main 函数结束时停止断路器
	// Stop the circuit breaker when the main function ends
	defer breaker.Stop()

	// 循环 10 次,每次使用断路器执行一个返回 nil 的函数
	// Loop 10 times, each time using the circuit breaker to execute a function that returns nil
	for i := 0; i < 10; i++ {
		_ = breaker.Do(func() error {
			return nil
		})
	}

	// =========================== Case1 ===========================

	// 定义一个返回 nil 的函数
	// Define a function that returns nil
	fn := func() error {
		return nil
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err := breaker.Do(fn)
	if err != nil {
		fmt.Printf("#Case1: Unexpected error: %v\n", err)
	} else {
		fmt.Printf("#Case1: Successful execution with default.\n")
	}

	// =========================== Case2 ===========================

	// 定义一个返回执行错误的函数
	// Define a function that returns an execution error
	fn = func() error {
		return executionError
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err = breaker.Do(fn)
	if err != nil {
		fmt.Printf("#Case2: Unexpected error: %v\n", err)
	}

	// =========================== Case3 ===========================

	// 定义一个接受函数,它接受除执行错误外的所有错误
	// Define an accept function, which accepts all errors except the execution error
	acceptable := func(err error) bool {
		return !errors.Is(err, executionError)
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err = breaker.DoWithAcceptable(fn, acceptable)
	if err != nil {
		fmt.Printf("#Case3: Unexpected error: %v\n", err)
	} else {
		fmt.Printf("#Case3: Failed execution with unacceptable.\n")
	}

	// =========================== Case4 ===========================

	// 定义一个接受函数,它接受执行错误
	// Define an accept function, which accepts the execution error
	acceptable = func(err error) bool {
		return errors.Is(err, executionError)
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err = breaker.DoWithAcceptable(fn, acceptable)
	if err != nil {
		fmt.Printf("#Case4: Unexpected error: %v\n", err)
	} else {
		fmt.Printf("#Case4: Failed execution with acceptable.\n")
	}

	// =========================== Case5 ===========================

	// 循环 20 次,每次使用断路器执行一个返回执行错误的函数
	// Loop 20 times, each time using the circuit breaker to execute a function that returns an execution error
	for i := 0; i < 20; i++ {
		_ = breaker.Do(func() error {
			return executionError
		})
	}

	// 定义一个回退函数,它返回回退错误
	// Define a fallback function, which returns a fallback error
	fallback := func(err error) error {
		return fallbackError
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err = breaker.DoWithFallback(fn, fallback)
	if err != nil {
		fmt.Printf("#Case5: Unexpected error: %v\n", err)
	} else {
		fmt.Printf("#Case5: Failed execution with fallback.\n")
	}

	// 等待 5 秒
	// Wait for 5 seconds
	time.Sleep(5 * time.Second)

	// =========================== Case6 ===========================

	// 定义一个返回 nil 的函数
	// Define a function that returns nil
	fn = func() error {
		return nil
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err = breaker.Do(fn)
	if err != nil {
		fmt.Printf("#Case6: Unexpected error: %v\n", err)
	} else {
		fmt.Printf("#Case6: Idle for 5 seconds, successful execution.\n")
	}
}

Result

$ go run demo.go
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
#Case1: Successful execution with default.
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnFailure: <nil>, execution error
#Case2: Unexpected error: execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.077
OnFailure: <nil>, execution error
#Case3: Unexpected error: execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.143
OnSuccess: <nil>
#Case4: Failed execution with acceptable.
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.133
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.188
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.235
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.278
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.316
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.35
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.381
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.409
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.435
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.458
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.04, failure ratio 0.48
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.077, failure ratio 0.5
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.111, failure ratio 0.519
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.143, failure ratio 0.536
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.172, failure ratio 0.552
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.2, failure ratio 0.567
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.226, failure ratio 0.581
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.25, failure ratio 0.594
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.273, failure ratio 0.606
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.294, failure ratio 0.618
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.314, failure ratio 0.629
OnFailure: <nil>, service unavailable
#Case5: Unexpected error: fallback error
OnAccept: <nil>, fuse ratio: 0.333, failure ratio 0.639
OnSuccess: <nil>
#Case6: Idle for 5 seconds, successful execution.

4.3 Retry

Here is an example of using the tripwire library with the retry module to create a circuit breaker with some cases. The code snippet is quite large, so please be patient.

package main

import (
	"errors"
	"fmt"
	"time"

	"github.com/shengyanli1982/retry"
	tp "github.com/shengyanli1982/tripwire"
	cb "github.com/shengyanli1982/tripwire/circuitbreaker"
)

// 定义两个全局错误变量:执行错误和回退错误
// Define two global error variables: execution error and fallback error
var (
	// executionError 是当执行函数时发生的错误
	// executionError is the error that occurs when executing the function
	executionError = errors.New("execution error")

	// fallbackError 是当执行回退函数时发生的错误
	// fallbackError is the error that occurs when executing the fallback function
	fallbackError = errors.New("fallback error")
)

// demoCallback 结构体实现了回调接口
// The demoCallback struct implements the callback interface
type demoCallback struct{}

// OnSuccess 方法在成功执行函数时被调用,打印一个消息和可选的错误
// The OnSuccess method is called when the function is successfully executed, printing a message and an optional error
func (d *demoCallback) OnSuccess(err error) {
	// 打印成功消息和可选的错误
	// Print success message and optional error
	fmt.Printf("OnSuccess: %v\n", err)
}

// OnFailure 方法在执行函数失败时被调用,打印一个消息和错误原因
// The OnFailure method is called when the function execution fails, printing a message and the reason for the error
func (d *demoCallback) OnFailure(err, reason error) {
	// 打印失败消息和错误原因
	// Print failure message and error reason
	fmt.Printf("OnFailure: %v, %v\n", err, reason)
}

// OnAccept 方法在接受错误时被调用,打印一个消息、熔断比例和失败比例
// The OnAccept method is called when an error is accepted, printing a message, the fuse ratio, and the failure ratio
func (d *demoCallback) OnAccept(reason error, fuse, failure float64) {
	// 打印接受错误的消息、熔断比例和失败比例
	// Print the message of accepting the error, the fuse ratio, and the failure ratio
	fmt.Printf("OnAccept: %v, fuse ratio: %v, failure ratio %v\n", reason, fuse, failure)
}

func main() {
	// 创建一个新的断路器配置,并设置回调函数为 demoCallback
	// Create a new circuit breaker configuration and set the callback function to demoCallback
	config := cb.NewConfig().WithCallback(&demoCallback{})

	// 创建一个新的断路器,使用 Google 断路器和给定的配置,并设置重试策略为默认策略
	// Create a new circuit breaker, using a Google circuit breaker and the given configuration, and set the retry strategy to the default strategy
	breaker := tp.New(tp.NewConfig().WithBreaker(cb.NewGoogleBreaker(config)).WithRetry(retry.New(nil)))

	// 在 main 函数结束时停止断路器
	// Stop the circuit breaker when the main function ends
	defer breaker.Stop()

	// 循环 10 次,每次使用断路器执行一个返回 nil 的函数
	// Loop 10 times, each time using the circuit breaker to execute a function that returns nil
	for i := 0; i < 10; i++ {
		_ = breaker.Do(func() error {
			// 这个函数不执行任何操作,只是简单地返回 nil
			// This function does nothing, it simply returns nil
			return nil
		})
	}

	// =========================== Case1 ===========================

	// 定义一个返回 nil 的函数
	// Define a function that returns nil
	fn := func() error {
		// 这个函数不执行任何操作,只是简单地返回 nil
		// This function does nothing, it simply returns nil
		return nil
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err := breaker.Do(fn)
	if err != nil {
		fmt.Printf("#Case1: Unexpected error: %v\n", err)
	} else {
		fmt.Printf("#Case1: Successful execution with default.\n")
	}

	// =========================== Case2 ===========================

	// 定义一个返回执行错误的函数
	// Define a function that returns the execution error
	fn = func() error {
		// 这个函数返回执行错误
		// This function returns the execution error
		return executionError
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err = breaker.Do(fn)
	if err != nil {
		fmt.Printf("#Case2: Unexpected error: %v\n", err)
	}

	// =========================== Case3 ===========================

	// 定义一个函数,该函数接受一个错误参数,如果错误不是执行错误,则返回 true,否则返回 false
	// Define a function that accepts an error parameter, if the error is not the execution error, return true, otherwise return false
	acceptable := func(err error) bool {
		return !errors.Is(err, executionError)
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err = breaker.DoWithAcceptable(fn, acceptable)
	if err != nil {
		fmt.Printf("#Case3: Unexpected error: %v\n", err)
	} else {
		fmt.Printf("#Case3: Failed execution with unacceptable.\n")
	}

	// =========================== Case4 ===========================

	// 定义一个函数,该函数接受一个错误参数,如果错误是执行错误,则返回 true,否则返回 false
	// Define a function that accepts an error parameter, if the error is the execution error, return true, otherwise return false
	acceptable = func(err error) bool {
		return errors.Is(err, executionError)
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err = breaker.DoWithAcceptable(fn, acceptable)
	if err != nil {
		fmt.Printf("#Case4: Unexpected error: %v\n", err)
	} else {
		fmt.Printf("#Case4: Failed execution with acceptable.\n")
	}

	// =========================== Case5 ===========================

	// 循环 10 次,每次使用断路器执行一个返回执行错误的函数
	// Loop 10 times, each time using the circuit breaker to execute a function that returns the execution error
	for i := 0; i < 10; i++ {
		_ = breaker.Do(func() error {
			return executionError
		})
	}

	// 定义一个回退函数,该函数接受一个错误参数,并返回回退错误
	// Define a fallback function that accepts an error parameter and returns the fallback error
	fallback := func(err error) error {
		return fallbackError
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err = breaker.DoWithFallback(fn, fallback)
	if err != nil {
		fmt.Printf("#Case5: Unexpected error: %v\n", err)
	} else {
		fmt.Printf("#Case5: Failed execution with fallback.\n")
	}

	// =========================== Case6 ===========================

	// 让程序休眠 5 秒
	// Let the program sleep for 5 seconds
	time.Sleep(5 * time.Second)

	// 定义一个返回 nil 的函数
	// Define a function that returns nil
	fn = func() error {
		return nil
	}

	// 使用断路器执行函数,并处理可能的错误
	// Use the circuit breaker to execute the function and handle possible errors
	err = breaker.Do(fn)
	if err != nil {
		fmt.Printf("#Case6: Unexpected error: %v\n", err)
	} else {
		fmt.Printf("#Case6: Idle for 5 seconds, successful execution.\n")
	}
}

Result

$ go run demo.go
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnSuccess: <nil>
#Case1: Successful execution with default.
OnAccept: <nil>, fuse ratio: 0, failure ratio 0
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.077
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.143
OnFailure: <nil>, execution error
#Case2: Unexpected error: retry attempts exceeded
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.2
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.25
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.333
OnFailure: <nil>, execution error
#Case3: Unexpected error: retry attempts exceeded
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.4
OnSuccess: <nil>
#Case4: Failed execution with acceptable.
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.4
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.5
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.125, failure ratio 0.667
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.25, failure ratio 0.75
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.318, failure ratio 0.818
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.318, failure ratio 0.818
OnFailure: <nil>, service unavailable
OnAccept: service unavailable, fuse ratio: 0.375, failure ratio 0.833
OnFailure: <nil>, service unavailable
OnAccept: service unavailable, fuse ratio: 0.318, failure ratio 0.818
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.318, failure ratio 0.818
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.375, failure ratio 0.833
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.455, failure ratio 0.909
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.4, failure ratio 0.9
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.455, failure ratio 0.909
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.4, failure ratio 0.9
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.25, failure ratio 0.875
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.333, failure ratio 0.889
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.333, failure ratio 0.889
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.25, failure ratio 0.875
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.333, failure ratio 0.889
OnFailure: <nil>, service unavailable
OnAccept: service unavailable, fuse ratio: 0.333, failure ratio 0.889
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.333, failure ratio 0.889
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.333, failure ratio 0.889
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.4, failure ratio 0.9
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.4, failure ratio 0.9
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.455, failure ratio 0.909
OnFailure: <nil>, execution error
OnAccept: <nil>, fuse ratio: 0.455, failure ratio 0.909
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.333, failure ratio 0.889
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.333, failure ratio 0.889
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.4, failure ratio 0.9
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.4, failure ratio 0.9
OnFailure: <nil>, execution error
OnAccept: service unavailable, fuse ratio: 0.4, failure ratio 0.9
OnFailure: <nil>, service unavailable
OnAccept: service unavailable, fuse ratio: 0.333, failure ratio 0.889
OnFailure: <nil>, service unavailable
OnAccept: <nil>, fuse ratio: 0.333, failure ratio 0.889
OnFailure: <nil>, execution error
#Case5: Unexpected error: retry attempts exceeded
OnAccept: <nil>, fuse ratio: 0, failure ratio 0.8
OnSuccess: <nil>
#Case6: Idle for 5 seconds, successful execution.

Thanks to

About

Tripwire is a Go-based circuit breaker that provides lightweight protection for high-traffic systems. It intelligently preemptively handles failures and ensures stability by automatically disconnecting based on threshold conditions.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages