circuitry

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2021 License: MIT Imports: 5 Imported by: 0

README

circuitry

circuitry is a circuit breaker implementation in Go.

Installation

Download and install :

$ go get github.com/cyberdelia/circuitry

Add it to your code :

import "github.com/cyberdelia/circuitry"

Usage

w, _ := circuitry.NewWindow(10, 10*time.Second)
circuit := circuitry.NewBreaker(40, 4, time.Minute, w)
if circuit.Allow() {
	err := DangerousStuff()
	circuit.Error(err) 
}

Dealing with panic :

func Safe() {
  w, _ := circuitry.NewWindow(10, 10*time.Second)
	circuit := circuitry.NewBreaker(40, 4, time.Minute, w)
	defer func() {
		if e := recover(); e != nil {
			circuit.Error(e.(error))
		}
	}()
	if circuit.Allow() {
		MightPanic()
		circuit.Error(nil)
	}
}

Or if failure is not an error :

w, _ := circuitry.NewWindow(10, 10*time.Second)
circuit := circuitry.NewBreaker(40, 4, time.Minute, w)
if circuit.Allow() {
	if DangerousStuff() {
		circuit.MarkSuccess()
	} else {
		circuit.MarkFailure()
	}
}

Or via a Command :

type Namer struct {
	Name string
}

func (n *Namer) Run() (interface{}, error) {
	rand.Seed(time.Now().UnixNano())
	if rand.Intn(4) >= 2 {
		return nil, fmt.Errorf("can't assign name: %s", n.Name)
	}
	return fmt.Sprintf("Your name is %s.", n.Name), nil
}

func (n *Namer) Fallback() interface{} {
	return fmt.Sprintf("Hello, %s.", n.Name)
}

func main() {
	cmd := &Namer{"Hal"}

	w, _ := circuitry.NewWindow(10, 10*time.Second)
	circuit := circuitry.NewBreaker(40, 4, time.Minute, w)
	value := circuitry.Execute(cmd, circuit)

	fmt.Println(value)
}

Documentation

Overview

A circuit breaker

Circuitry is a circuit breaker similar to Hystrix:

w, _ := NewWindow(10, 10*time.Second)
circuit := circuitry.NewBreaker(15, 100, time.Minute, w)
if circuit.Allow() {
    err := DangerousStuff()
    circuit.Error(err)
}

Or via a Command:

type Namer struct {
    Name string
}

func (n *Namer) Run() (interface{}, error) {
    rand.Seed(time.Now().UnixNano())
    if rand.Intn(4) >= 2 {
        return nil, fmt.Errorf("can't assign name: %s", n.Name)
    }
    return fmt.Sprintf("Your name is %s.", n.Name), nil
}

func (n *Namer) Fallback() interface{} {
    return fmt.Sprintf("Hello, %s.", n.Name)
}

func main() {
    cmd := &Namer{"Hal"}

    w, _ := circuitry.NewWindow(10, 10*time.Second)
    circuit := circuitry.NewBreaker(40, 4, time.Minute, w)
    value := circuitry.Execute(cmd, circuit)

    fmt.Println(value)
}

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrBucketSize = errors.New("bucket duration and size must divide equally")

Functions

func Execute

func Execute(c Command, b *CircuitBreaker) interface{}

Execute the given command against the given circuit breaker.

Example
b := NewBreaker(40, 0, time.Minute, window())
v := Execute(&alwaysSucceed{}, b)
fmt.Println(v)
Output:

Types

type CircuitBreaker

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

CircuitBreaker represents a circuit breaker.

func NewBreaker

func NewBreaker(errors, volume int64, timeout time.Duration, w *Window) *CircuitBreaker

Create a new circuit breaker.

Example
w, _ := NewWindow(10, 10*time.Second)
circuit := NewBreaker(40, 4, time.Minute, w)
if circuit.Allow() {
	circuit.Error(fmt.Errorf("forced error: %s", "example"))
}
Output:

func (*CircuitBreaker) Allow

func (b *CircuitBreaker) Allow() bool

Allow requests to proceed or not.

func (*CircuitBreaker) Close

func (b *CircuitBreaker) Close()

Close the circuit.

func (*CircuitBreaker) Error

func (b *CircuitBreaker) Error(err error)

Pass error to the to the circuit breaker.

func (*CircuitBreaker) ForceClose

func (b *CircuitBreaker) ForceClose()

Force close the circuit.

func (*CircuitBreaker) ForceOpen

func (b *CircuitBreaker) ForceOpen()

Force open the circuit.

func (*CircuitBreaker) IsClosed

func (b *CircuitBreaker) IsClosed() bool

Reports if the circuit is closed.

func (*CircuitBreaker) IsForced

func (b *CircuitBreaker) IsForced() bool

Reports if the circuit is forced.

func (*CircuitBreaker) IsOpen

func (b *CircuitBreaker) IsOpen() bool

Reports if the circuit is open.

func (*CircuitBreaker) MarkFailure

func (b *CircuitBreaker) MarkFailure()

Record a failure.

func (*CircuitBreaker) MarkShortCircuited

func (b *CircuitBreaker) MarkShortCircuited()

Record a rejection.

func (*CircuitBreaker) MarkSuccess

func (b *CircuitBreaker) MarkSuccess()

Record a successful operation.

func (*CircuitBreaker) Open

func (b *CircuitBreaker) Open()

Open the circuit.

type Command

type Command interface {
	Run() (interface{}, error)
	Fallback() interface{}
}

Command represents a piece of code you want to run and a fallback value.

type Window

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

func NewWindow

func NewWindow(n int, d time.Duration) (*Window, error)

Create a new window of duration d containing n buckets.

Example
window, _ := NewWindow(10, 10*time.Second)
window.Reset()
Output:

func (*Window) Errors

func (w *Window) Errors() int64

Return the percentage of errors (failures and short-circuit).

func (*Window) Failures

func (w *Window) Failures() (failures int64)

Return the total of failures.

func (*Window) Reset

func (w *Window) Reset()

Reset window statistics.

func (*Window) ShortCircuited

func (w *Window) ShortCircuited() (shortcircuit int64)

Return the total of short-circuit.

func (*Window) Successes

func (w *Window) Successes() (successes int64)

Return the total of successes.

func (*Window) Total

func (w *Window) Total() (total int64)

Return the total number of access (failures, success and short-circuit).

Jump to

Keyboard shortcuts

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