breaker

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: MIT Imports: 8 Imported by: 0

README

Go Reference tests codecov GitHub release (latest SemVer) GitHub go.mod Go version

Breaker

Breaker is a middleware for Fox that rejects requests to a failing route, using the adaptive throttling described in the Google SRE book.

Disclaimer

The current API is not yet stabilized. Breaking changes may occur before v1.0.0 and will be noted on the release note.

Getting started

Installation
go get -u github.com/fox-toolkit/breaker
Feature
  • One breaker per route, or one breaker shared by several routes.
  • No lock on the request path and no allocation.
  • Configurable failure ratio, window, cap and minimum number of requests.
  • Configurable failure definition and rejection response.
Usage
package main

import (
	"errors"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"

	"github.com/fox-toolkit/breaker"
	"github.com/fox-toolkit/fox"
)

func main() {
	// One breaker per route.
	mw, err := breaker.Middleware()
	if err != nil {
		log.Fatalln(err)
	}

	// One breaker shared by every route it wraps.
	b, err := breaker.New(breaker.WithFailureRatio(0.3))
	if err != nil {
		log.Fatalln(err)
	}

	f := fox.MustRouter()

	api, _ := url.Parse("http://127.0.0.1:8081")
	apiProxy := fox.WrapH(httputil.NewSingleHostReverseProxy(api))
	f.MustAdd(fox.MethodAny, "/api/*{any}", apiProxy, fox.WithMiddleware(mw))

	orders, _ := url.Parse("http://127.0.0.1:8082")
	ordersProxy := fox.WrapH(httputil.NewSingleHostReverseProxy(orders))
	f.MustAdd(fox.MethodAny, "/orders", ordersProxy, fox.WithMiddleware(b.Middleware()))
	f.MustAdd(fox.MethodAny, "/orders/{id}", ordersProxy, fox.WithMiddleware(b.Middleware()))

	if err := http.ListenAndServe(":8080", f); err != nil && !errors.Is(err, http.ErrServerClosed) {
		log.Fatalln(err)
	}
}

To apply the breaker to every route of the router, prefer registering it for route handlers.

mw, err := breaker.Middleware()
if err != nil {
	log.Fatalln(err)
}

// One breaker per route, for every route of the router.
f := fox.MustRouter(fox.WithMiddlewareFor(fox.RouteHandler, mw))

Documentation

Index

Constants

View Source
const (
	// DefaultFailureRatio is the default failure ratio above which requests are rejected.
	DefaultFailureRatio = 0.5
	// DefaultMinRequests is the default number of requests in the window below which no request is rejected.
	DefaultMinRequests = 20
	// DefaultWindow is the default duration of the measurement window.
	DefaultWindow = 10 * time.Second
	// DefaultMaxRejectRatio is the default maximum ratio of rejected requests.
	DefaultMaxRejectRatio = 0.9
)

Variables

View Source
var ErrInvalidConfig = errors.New("invalid config")

Functions

func DefaultFailure

func DefaultFailure(c *fox.Context) bool

DefaultFailure reports a response status of 502, 503 or 504 as a failure.

func DefaultReject

func DefaultReject(c *fox.Context)

DefaultReject responds with 503 Service Unavailable.

func Middleware

func Middleware(opts ...Option) (fox.MiddlewareFunc, error)

Middleware returns a fox.MiddlewareFunc that probabilistically rejects requests when the failure ratio goes above the configured ratio, based on the adaptive throttling described in the Google SRE book. Each route gets its own instance of a given breaker. One instance can reject requests while another does not, their state is not shared. To share state across routes, use New.

Types

type Breaker added in v0.2.0

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

Breaker is the state shared by every handler wrapped by its middleware.

func New added in v0.2.0

func New(opts ...Option) (*Breaker, error)

New returns a Breaker that probabilistically rejects requests when the failure ratio goes above the configured ratio. Its state is shared by every handler wrapped by Breaker.Middleware.

func (*Breaker) Middleware added in v0.2.0

func (b *Breaker) Middleware() fox.MiddlewareFunc

Middleware returns a fox.MiddlewareFunc that uses the state of b on every handler it wraps.

func (*Breaker) RejectRatio added in v0.2.0

func (b *Breaker) RejectRatio() float64

RejectRatio returns the probability that the next request is rejected.

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option configures the middleware.

func WithFailure

func WithFailure(fn func(c *fox.Context) bool) Option

WithFailure sets the function that reports whether a handled request failed. The default is DefaultFailure.

func WithFailureRatio

func WithFailureRatio(ratio float64) Option

WithFailureRatio sets the failure ratio, in [0, 1), above which requests start to be rejected. The default is DefaultFailureRatio.

func WithMaxRejectRatio

func WithMaxRejectRatio(ratio float64) Option

WithMaxRejectRatio sets the maximum ratio, in (0, 1], of rejected requests. The remaining requests always reach the handler, which lets the middleware detect a recovery. The default is DefaultMaxRejectRatio.

func WithMinRequests

func WithMinRequests(n int) Option

WithMinRequests sets the number of requests in the window below which no request is rejected. The default is DefaultMinRequests.

func WithRejectHandler

func WithRejectHandler(handler fox.HandlerFunc) Option

WithRejectHandler sets the handler called for rejected requests. The default is DefaultReject.

func WithWindow

func WithWindow(d time.Duration) Option

WithWindow sets the duration of the measurement window, between 1s and 10m. The default is DefaultWindow.

Jump to

Keyboard shortcuts

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