circuitbreaker

package
v1.9.3 Latest Latest
Warning

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

Go to latest
Published: Sep 6, 2024 License: MIT Imports: 7 Imported by: 2

README

circuitbreaker

Circuit Breaker for web middleware and rpc interceptor.


Example of use

gin circuit breaker middleware

import "github.com/zhufuyi/sponge/pkg/shield/circuitbreaker"

// CircuitBreaker a circuit breaker middleware
func CircuitBreaker(opts ...CircuitBreakerOption) gin.HandlerFunc {
	o := defaultCircuitBreakerOptions()
	o.apply(opts...)

	return func(c *gin.Context) {
		breaker := o.group.Get(c.FullPath()).(circuitbreaker.CircuitBreaker)
		if err := breaker.Allow(); err != nil {
			// NOTE: when client reject request locally, keep adding counter let the drop ratio higher.
			breaker.MarkFailed()
			response.Output(c, http.StatusServiceUnavailable, err.Error())
			c.Abort()
			return
		}

		c.Next()

		code := c.Writer.Status()
		// NOTE: need to check internal and service unavailable error, e.g. http.StatusInternalServerError
		_, isHit := o.validCodes[code]
		if isHit {
			breaker.MarkFailed()
		} else {
			breaker.MarkSuccess()
		}
	}
}

rpc server circuit breaker interceptor

import "github.com/zhufuyi/sponge/pkg/shield/circuitbreaker"

// UnaryServerCircuitBreaker server-side unary circuit breaker interceptor
func UnaryServerCircuitBreaker(opts ...CircuitBreakerOption) grpc.UnaryServerInterceptor {
	o := defaultCircuitBreakerOptions()
	o.apply(opts...)

	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
		breaker := o.group.Get(info.FullMethod).(circuitbreaker.CircuitBreaker)
		if err := breaker.Allow(); err != nil {
			// NOTE: when client reject request locally, keep adding let the drop ratio higher.
			breaker.MarkFailed()
			return nil, errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
		}

		reply, err := handler(ctx, req)
		if err != nil {
			// NOTE: need to check internal and service unavailable error
			s, ok := status.FromError(err)
			_, isHit := o.validCodes[s.Code()]
			if ok && isHit {
				breaker.MarkFailed()
			} else {
				breaker.MarkSuccess()
			}
		}

		return reply, err
	}
}

Documentation

Overview

Package circuitbreaker is an adaptive circuit breaker library, support for use in gin middleware and grpc interceptors.

Index

Constants

View Source
const (
	// StateOpen when circuit breaker open, request not allowed, after sleep
	// some duration, allow one single request for testing the health, if ok
	// then state reset to closed, if not continue the step.
	StateOpen int32 = iota
	// StateClosed when circuit breaker closed, request allowed, the breaker
	// calc the succeed ratio, if request num greater request setting and
	// ratio lower than the setting ratio, then reset state to open.
	StateClosed
)

Variables

View Source
var ErrNotAllowed = errors.New("circuitbreaker: not allowed for circuit open")

ErrNotAllowed error not allowed.

Functions

This section is empty.

Types

type Breaker

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

Breaker is a sre CircuitBreaker pattern.

func (*Breaker) Allow

func (b *Breaker) Allow() error

Allow request if error returns nil.

func (*Breaker) MarkFailed

func (b *Breaker) MarkFailed()

MarkFailed mark request is failed.

func (*Breaker) MarkSuccess

func (b *Breaker) MarkSuccess()

MarkSuccess mark request is success.

type CircuitBreaker

type CircuitBreaker interface {
	Allow() error
	MarkSuccess()
	MarkFailed()
}

CircuitBreaker is a circuit breaker.

func NewBreaker

func NewBreaker(opts ...Option) CircuitBreaker

NewBreaker return a sreBresker with options

type Option

type Option func(*options)

Option is sre breaker option function.

func WithBucket

func WithBucket(b int) Option

WithBucket set the bucket number in a window duration.

func WithRequest

func WithRequest(r int64) Option

WithRequest with the minimum number of requests allowed.

func WithSuccess

func WithSuccess(s float64) Option

WithSuccess with the K = 1 / Success value of sre breaker, default success is 0.5 Reducing the K will make adaptive throttling behave more aggressively, Increasing the K will make adaptive throttling behave less aggressively.

func WithWindow

func WithWindow(d time.Duration) Option

WithWindow with the duration size of the statistical window.

Jump to

Keyboard shortcuts

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