Giter Club home page Giter Club logo

gobreaker's People

Contributors

akashhansda avatar aryszka avatar bbaassssiiee avatar bnm3k avatar dmarkhas avatar dvrkps avatar enrichman avatar enrico204 avatar johanavril avatar kalbasit avatar kunalkapadia avatar rhysd avatar yoshiyukimineo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gobreaker's Issues

race conditions

When i looked into the code I was wondering if this package would be aware of go routines.
When it would be used in http handlers to handle calls of remote services , which is often the case in my implementation . The following test shows up that it is not aware of go routines even if there is a testcase in the package tests that tries to run them in parallel.

~/Desktop/Dev/go/sony/gobreaker:$ go test -race
==================
WARNING: DATA RACE
Read at 0x00c0001160d0 by goroutine 11:
  runtime.convT2Enoptr()
      /usr/local/go/src/runtime/iface.go:379 +0x0
  github.com/sony/gobreaker.TestCustomCircuitBreaker()
      /Users/rl/Desktop/Dev/go/sony/gobreaker/gobreaker_test.go:260 +0x11db
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:909 +0x199

Previous write at 0x00c0001160d0 by goroutine 12:
  github.com/sony/gobreaker.(*CircuitBreaker).beforeRequest()
      /Users/rl/Desktop/Dev/go/sony/gobreaker/gobreaker.go:56 +0x191
  github.com/sony/gobreaker.(*CircuitBreaker).Execute()
      /Users/rl/Desktop/Dev/go/sony/gobreaker/gobreaker.go:204 +0x63
  github.com/sony/gobreaker.succeedLater.func1()
      /Users/rl/Desktop/Dev/go/sony/gobreaker/gobreaker_test.go:38 +0x69

Goroutine 11 (running) created at:
  testing.(*T).Run()
      /usr/local/go/src/testing/testing.go:960 +0x651
  testing.runTests.func1()
      /usr/local/go/src/testing/testing.go:1202 +0xa6
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:909 +0x199
  testing.runTests()
      /usr/local/go/src/testing/testing.go:1200 +0x521
  testing.(*M).Run()
      /usr/local/go/src/testing/testing.go:1117 +0x2ff
  main.main()
      _testmain.go:58 +0x223

Goroutine 12 (running) created at:
  github.com/sony/gobreaker.succeedLater()
      /Users/rl/Desktop/Dev/go/sony/gobreaker/gobreaker_test.go:37 +0x82
  github.com/sony/gobreaker.TestCustomCircuitBreaker()
      /Users/rl/Desktop/Dev/go/sony/gobreaker/gobreaker_test.go:258 +0x113a
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:909 +0x199
==================
--- FAIL: TestCustomCircuitBreaker (0.10s)
    testing.go:853: race detected during execution of test
FAIL
exit status 1
FAIL	github.com/sony/gobreaker	2.213s

What do you think about such a situation? Is it worth to invest in a PR to make it aware of go routines and in addition to that moving from the expensive sync.Mutex handling towards go channles so that always only one go routine is maintaining the counters and state?

two-step pass check and outcome reporting

Hi, I'd like to have the possibility to check if a request can pass through and setting the outcome in separate steps, outside the Execute() method. This would be possible if the breaker had the following additional methods:

  • Allow() bool: would tell if the breaker is closed, or, in half open state, can the request pass through.
  • Success(): report a successful outcome
  • Failure(): report a failed outcome

Allow() would be basically a visible wrapper around beforeRequest(), while Failure() and Success() around afterRequest().

This would enable using the breaker in an asynchronous way, where the check for passing and reporting the outcome are not in a single control flow.

I'd be happy to make a pull request.

breaker per url

We would like to use circuit breaker pattern while integrating with 3rd party API's, however we want to isolate failures at integration + customer level.

For example, example.com/test is one integration can be used by customer 1 and anotherexample.com/test is another integration used by customer 2.

Let's say, when example.com/test is down and circuit trips after threshold, we do not want to affect customer 2 and others except customer of that particular integration which is down, is this possible?

I guess challenge is we upfront do not know how many integrations will be needed so we need some dynamic way to define circuit breakers per combination of integration and customer (unique id of integration might be sufficient)

breaker for host+service

i want to use gobreaker in my project, i have chained api that looks like this:
request -> api gw -> oauth -> svc1 -> svc2 -> response

oauth, svc1 can work on multiple hosts and if one fails another can work.
doe i need to create different instances of breaker for such thing? or how to deal with such cases?

example: HTTP circuit breaker doesn't consider HTTP status codes which are more indicative of retryable errors

The circuit breaker pattern as per the linked docs is to allow retrying of operations that are less likely to fail. With the current code in example/ if I encounter a 404, it'll just return the 404 HTML page and moreover without any operational context hence defeating the pattern aimed for :-(

func Get(url string) ([]byte, error) {
body, err := cb.Execute(func() (interface{}, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
})
if err != nil {
return nil, err
}
return body.([]byte), nil
}
func main() {
body, err := Get("http://www.google.com/robots.txt")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))
}

There should be a way in which the example HTTP circuit breaker looks at the returned HTTP status codes. There are some for which you should not retry unless some conditions change e.g. authorization and authentication problems, not found and legal issue status codes.

At bare minimum please make the example more resilient with error checking such as

defer res.Body.Close()

if res.StatusCode/100 != 2 { // Not a 2XX successful response
    ... // Handle the status code in here
}

is circuit breaker threadsafe?

Do I need to use a mutex when calling cb.Execute from multiple goroutines?
as it seems, counts won't be calculated correctly and need to be synchronized

Reproducing "too many requests"

Hello guys, our production is suffers from "too many requests" and I'm struggle to reproduce this error.
I set CB to half-open state, but I cannot reproduce that error, it goes to only to close or open state.
Can you please explain what steps I should do to get it.

Confusion about ErrTooManyRequests error

Hi,

Thanks a lot for your library, it's simple, yet powerful! :)
Could you please clarify one confusion I have about ErrTooManyRequests error? I don't quite understand from the code when this error could happen.
I see the if state == StateHalfOpen && cb.counts.Requests >= cb.maxRequests condition in the beforeRequest() method but from the rest of the code it doesn't look like it could ever be met. This is because we either get enough consecutive requests to trip circuit to close with this condition if cb.counts.ConsecutiveSuccesses >= cb.maxRequests { cb.setState(StateClosed, now) } or we go back to open state because of a single failure in onFailure(). Or did I misunderstand something?

Why don't use a rolling window to maintain the counts?

I just give a quite look to this library. This circuit breaker is mighty simple (compared with a Hystrix-like implementation) but still powerful.

However, I have a question about the counter expiration. Hystrix uses a rolling window to store the counts. This library doesn't maintain a rolling window, instead it drops the whole counts when the time interval is passed.

There may be a problem. Considered we use 10s as an interval, and we have 10000 requests come between 1s ~ 11s, 1000 requests per each second. The last 900 requests fail in the 11s. If the rolling window is used, the error rate will be 9% (900 / 10000). However, if we are unfortunate enough that the counts are expired in 10s, the error will be 90%, since we will recount the requests from the 11s.

Maybe I am missing something. Please let me know if I am wrong.

start a new release?

What about start a new release like v0.4.0, for the v0.3.0 is outdated... Thanks a lot

[question/proposal] Monitoring

What is the way to collect metrics for monitoring?
It would be good to get more information about the statistic of circuit breaker than just status: open, half-open and closed.

Count contains enough information about CB condition.

type Counts struct {
	Requests             uint32
	TotalSuccesses       uint32
	TotalFailures        uint32
	ConsecutiveSuccesses uint32
	ConsecutiveFailures  uint32
}

Circuitbreaker not performing MaxRequests operations in Half-open state

It is stated that

// MaxRequests is the maximum number of requests allowed to pass through
// when the CircuitBreaker is half-open.
// If MaxRequests is 0, the CircuitBreaker allows only 1 request.

Considering this, I assume that the circuit breaker will perform MaxRequests count of operations before opening? But it doesn't.

Here is a reproducible code

package main

import (
	"errors"
	"fmt"
	"github.com/sony/gobreaker"
	"time"
)

func main() {
	cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{
		Name:          "sad",
		MaxRequests:   20,
		Interval:      time.Second * 10,
		Timeout:       time.Second * 1,
		ReadyToTrip: func(counts gobreaker.Counts) bool {
			failureRatio := float64(counts.TotalFailures) / float64(counts.Requests)
			if failureRatio > 0.7 {
				fmt.Printf("will trip? %+v\n", counts)
			}
			return counts.Requests >= 100 && failureRatio > 0.7
		},
		OnStateChange: func(name string, from gobreaker.State, to gobreaker.State) {
			fmt.Printf("Circuit breaker %v state change from %v to %v\n", name, from, to)
		},
	})

	for {
		cb.Execute(func() (interface{}, error) {
			return nil, fun()
		})
	}
}

func fun() error {
	fmt.Println("RUNNING")
	return errors.New("LMAO")
}

This prints...

RUNNING
will trip? {Requests:1 TotalSuccesses:0 TotalFailures:1 ConsecutiveSuccesses:0 ConsecutiveFailures:1}
RUNNING
will trip? {Requests:2 TotalSuccesses:0 TotalFailures:2 ConsecutiveSuccesses:0 ConsecutiveFailures:2}
RUNNING
will trip? {Requests:3 TotalSuccesses:0 TotalFailures:3 ConsecutiveSuccesses:0 ConsecutiveFailures:3}
RUNNING
will trip? {Requests:4 TotalSuccesses:0 TotalFailures:4 ConsecutiveSuccesses:0 ConsecutiveFailures:4}
RUNNING
will trip? {Requests:5 TotalSuccesses:0 TotalFailures:5 ConsecutiveSuccesses:0 ConsecutiveFailures:5}
RUNNING
will trip? {Requests:6 TotalSuccesses:0 TotalFailures:6 ConsecutiveSuccesses:0 ConsecutiveFailures:6}
RUNNING
will trip? {Requests:7 TotalSuccesses:0 TotalFailures:7 ConsecutiveSuccesses:0 ConsecutiveFailures:7}
RUNNING
will trip? {Requests:8 TotalSuccesses:0 TotalFailures:8 ConsecutiveSuccesses:0 ConsecutiveFailures:8}
RUNNING
will trip? {Requests:9 TotalSuccesses:0 TotalFailures:9 ConsecutiveSuccesses:0 ConsecutiveFailures:9}
RUNNING
will trip? {Requests:10 TotalSuccesses:0 TotalFailures:10 ConsecutiveSuccesses:0 ConsecutiveFailures:10}
RUNNING
will trip? {Requests:11 TotalSuccesses:0 TotalFailures:11 ConsecutiveSuccesses:0 ConsecutiveFailures:11}
RUNNING
will trip? {Requests:12 TotalSuccesses:0 TotalFailures:12 ConsecutiveSuccesses:0 ConsecutiveFailures:12}
RUNNING
will trip? {Requests:13 TotalSuccesses:0 TotalFailures:13 ConsecutiveSuccesses:0 ConsecutiveFailures:13}
RUNNING
will trip? {Requests:14 TotalSuccesses:0 TotalFailures:14 ConsecutiveSuccesses:0 ConsecutiveFailures:14}
RUNNING
will trip? {Requests:15 TotalSuccesses:0 TotalFailures:15 ConsecutiveSuccesses:0 ConsecutiveFailures:15}
RUNNING
will trip? {Requests:16 TotalSuccesses:0 TotalFailures:16 ConsecutiveSuccesses:0 ConsecutiveFailures:16}
RUNNING
will trip? {Requests:17 TotalSuccesses:0 TotalFailures:17 ConsecutiveSuccesses:0 ConsecutiveFailures:17}
RUNNING
will trip? {Requests:18 TotalSuccesses:0 TotalFailures:18 ConsecutiveSuccesses:0 ConsecutiveFailures:18}
RUNNING
will trip? {Requests:19 TotalSuccesses:0 TotalFailures:19 ConsecutiveSuccesses:0 ConsecutiveFailures:19}
RUNNING
will trip? {Requests:20 TotalSuccesses:0 TotalFailures:20 ConsecutiveSuccesses:0 ConsecutiveFailures:20}
RUNNING
will trip? {Requests:21 TotalSuccesses:0 TotalFailures:21 ConsecutiveSuccesses:0 ConsecutiveFailures:21}
RUNNING
will trip? {Requests:22 TotalSuccesses:0 TotalFailures:22 ConsecutiveSuccesses:0 ConsecutiveFailures:22}
RUNNING
will trip? {Requests:23 TotalSuccesses:0 TotalFailures:23 ConsecutiveSuccesses:0 ConsecutiveFailures:23}
RUNNING
will trip? {Requests:24 TotalSuccesses:0 TotalFailures:24 ConsecutiveSuccesses:0 ConsecutiveFailures:24}
RUNNING
will trip? {Requests:25 TotalSuccesses:0 TotalFailures:25 ConsecutiveSuccesses:0 ConsecutiveFailures:25}
RUNNING
will trip? {Requests:26 TotalSuccesses:0 TotalFailures:26 ConsecutiveSuccesses:0 ConsecutiveFailures:26}
RUNNING
will trip? {Requests:27 TotalSuccesses:0 TotalFailures:27 ConsecutiveSuccesses:0 ConsecutiveFailures:27}
RUNNING
will trip? {Requests:28 TotalSuccesses:0 TotalFailures:28 ConsecutiveSuccesses:0 ConsecutiveFailures:28}
RUNNING
will trip? {Requests:29 TotalSuccesses:0 TotalFailures:29 ConsecutiveSuccesses:0 ConsecutiveFailures:29}
RUNNING
will trip? {Requests:30 TotalSuccesses:0 TotalFailures:30 ConsecutiveSuccesses:0 ConsecutiveFailures:30}
RUNNING
will trip? {Requests:31 TotalSuccesses:0 TotalFailures:31 ConsecutiveSuccesses:0 ConsecutiveFailures:31}
RUNNING
will trip? {Requests:32 TotalSuccesses:0 TotalFailures:32 ConsecutiveSuccesses:0 ConsecutiveFailures:32}
RUNNING
will trip? {Requests:33 TotalSuccesses:0 TotalFailures:33 ConsecutiveSuccesses:0 ConsecutiveFailures:33}
RUNNING
will trip? {Requests:34 TotalSuccesses:0 TotalFailures:34 ConsecutiveSuccesses:0 ConsecutiveFailures:34}
RUNNING
will trip? {Requests:35 TotalSuccesses:0 TotalFailures:35 ConsecutiveSuccesses:0 ConsecutiveFailures:35}
RUNNING
will trip? {Requests:36 TotalSuccesses:0 TotalFailures:36 ConsecutiveSuccesses:0 ConsecutiveFailures:36}
RUNNING
will trip? {Requests:37 TotalSuccesses:0 TotalFailures:37 ConsecutiveSuccesses:0 ConsecutiveFailures:37}
RUNNING
will trip? {Requests:38 TotalSuccesses:0 TotalFailures:38 ConsecutiveSuccesses:0 ConsecutiveFailures:38}
RUNNING
will trip? {Requests:39 TotalSuccesses:0 TotalFailures:39 ConsecutiveSuccesses:0 ConsecutiveFailures:39}
RUNNING
will trip? {Requests:40 TotalSuccesses:0 TotalFailures:40 ConsecutiveSuccesses:0 ConsecutiveFailures:40}
RUNNING
will trip? {Requests:41 TotalSuccesses:0 TotalFailures:41 ConsecutiveSuccesses:0 ConsecutiveFailures:41}
RUNNING
will trip? {Requests:42 TotalSuccesses:0 TotalFailures:42 ConsecutiveSuccesses:0 ConsecutiveFailures:42}
RUNNING
will trip? {Requests:43 TotalSuccesses:0 TotalFailures:43 ConsecutiveSuccesses:0 ConsecutiveFailures:43}
RUNNING
will trip? {Requests:44 TotalSuccesses:0 TotalFailures:44 ConsecutiveSuccesses:0 ConsecutiveFailures:44}
RUNNING
will trip? {Requests:45 TotalSuccesses:0 TotalFailures:45 ConsecutiveSuccesses:0 ConsecutiveFailures:45}
RUNNING
will trip? {Requests:46 TotalSuccesses:0 TotalFailures:46 ConsecutiveSuccesses:0 ConsecutiveFailures:46}
RUNNING
will trip? {Requests:47 TotalSuccesses:0 TotalFailures:47 ConsecutiveSuccesses:0 ConsecutiveFailures:47}
RUNNING
will trip? {Requests:48 TotalSuccesses:0 TotalFailures:48 ConsecutiveSuccesses:0 ConsecutiveFailures:48}
RUNNING
will trip? {Requests:49 TotalSuccesses:0 TotalFailures:49 ConsecutiveSuccesses:0 ConsecutiveFailures:49}
RUNNING
will trip? {Requests:50 TotalSuccesses:0 TotalFailures:50 ConsecutiveSuccesses:0 ConsecutiveFailures:50}
RUNNING
will trip? {Requests:51 TotalSuccesses:0 TotalFailures:51 ConsecutiveSuccesses:0 ConsecutiveFailures:51}
RUNNING
will trip? {Requests:52 TotalSuccesses:0 TotalFailures:52 ConsecutiveSuccesses:0 ConsecutiveFailures:52}
RUNNING
will trip? {Requests:53 TotalSuccesses:0 TotalFailures:53 ConsecutiveSuccesses:0 ConsecutiveFailures:53}
RUNNING
will trip? {Requests:54 TotalSuccesses:0 TotalFailures:54 ConsecutiveSuccesses:0 ConsecutiveFailures:54}
RUNNING
will trip? {Requests:55 TotalSuccesses:0 TotalFailures:55 ConsecutiveSuccesses:0 ConsecutiveFailures:55}
RUNNING
will trip? {Requests:56 TotalSuccesses:0 TotalFailures:56 ConsecutiveSuccesses:0 ConsecutiveFailures:56}
RUNNING
will trip? {Requests:57 TotalSuccesses:0 TotalFailures:57 ConsecutiveSuccesses:0 ConsecutiveFailures:57}
RUNNING
will trip? {Requests:58 TotalSuccesses:0 TotalFailures:58 ConsecutiveSuccesses:0 ConsecutiveFailures:58}
RUNNING
will trip? {Requests:59 TotalSuccesses:0 TotalFailures:59 ConsecutiveSuccesses:0 ConsecutiveFailures:59}
RUNNING
will trip? {Requests:60 TotalSuccesses:0 TotalFailures:60 ConsecutiveSuccesses:0 ConsecutiveFailures:60}
RUNNING
will trip? {Requests:61 TotalSuccesses:0 TotalFailures:61 ConsecutiveSuccesses:0 ConsecutiveFailures:61}
RUNNING
will trip? {Requests:62 TotalSuccesses:0 TotalFailures:62 ConsecutiveSuccesses:0 ConsecutiveFailures:62}
RUNNING
will trip? {Requests:63 TotalSuccesses:0 TotalFailures:63 ConsecutiveSuccesses:0 ConsecutiveFailures:63}
RUNNING
will trip? {Requests:64 TotalSuccesses:0 TotalFailures:64 ConsecutiveSuccesses:0 ConsecutiveFailures:64}
RUNNING
will trip? {Requests:65 TotalSuccesses:0 TotalFailures:65 ConsecutiveSuccesses:0 ConsecutiveFailures:65}
RUNNING
will trip? {Requests:66 TotalSuccesses:0 TotalFailures:66 ConsecutiveSuccesses:0 ConsecutiveFailures:66}
RUNNING
will trip? {Requests:67 TotalSuccesses:0 TotalFailures:67 ConsecutiveSuccesses:0 ConsecutiveFailures:67}
RUNNING
will trip? {Requests:68 TotalSuccesses:0 TotalFailures:68 ConsecutiveSuccesses:0 ConsecutiveFailures:68}
RUNNING
will trip? {Requests:69 TotalSuccesses:0 TotalFailures:69 ConsecutiveSuccesses:0 ConsecutiveFailures:69}
RUNNING
will trip? {Requests:70 TotalSuccesses:0 TotalFailures:70 ConsecutiveSuccesses:0 ConsecutiveFailures:70}
RUNNING
will trip? {Requests:71 TotalSuccesses:0 TotalFailures:71 ConsecutiveSuccesses:0 ConsecutiveFailures:71}
RUNNING
will trip? {Requests:72 TotalSuccesses:0 TotalFailures:72 ConsecutiveSuccesses:0 ConsecutiveFailures:72}
RUNNING
will trip? {Requests:73 TotalSuccesses:0 TotalFailures:73 ConsecutiveSuccesses:0 ConsecutiveFailures:73}
RUNNING
will trip? {Requests:74 TotalSuccesses:0 TotalFailures:74 ConsecutiveSuccesses:0 ConsecutiveFailures:74}
RUNNING
will trip? {Requests:75 TotalSuccesses:0 TotalFailures:75 ConsecutiveSuccesses:0 ConsecutiveFailures:75}
RUNNING
will trip? {Requests:76 TotalSuccesses:0 TotalFailures:76 ConsecutiveSuccesses:0 ConsecutiveFailures:76}
RUNNING
will trip? {Requests:77 TotalSuccesses:0 TotalFailures:77 ConsecutiveSuccesses:0 ConsecutiveFailures:77}
RUNNING
will trip? {Requests:78 TotalSuccesses:0 TotalFailures:78 ConsecutiveSuccesses:0 ConsecutiveFailures:78}
RUNNING
will trip? {Requests:79 TotalSuccesses:0 TotalFailures:79 ConsecutiveSuccesses:0 ConsecutiveFailures:79}
RUNNING
will trip? {Requests:80 TotalSuccesses:0 TotalFailures:80 ConsecutiveSuccesses:0 ConsecutiveFailures:80}
RUNNING
will trip? {Requests:81 TotalSuccesses:0 TotalFailures:81 ConsecutiveSuccesses:0 ConsecutiveFailures:81}
RUNNING
will trip? {Requests:82 TotalSuccesses:0 TotalFailures:82 ConsecutiveSuccesses:0 ConsecutiveFailures:82}
RUNNING
will trip? {Requests:83 TotalSuccesses:0 TotalFailures:83 ConsecutiveSuccesses:0 ConsecutiveFailures:83}
RUNNING
will trip? {Requests:84 TotalSuccesses:0 TotalFailures:84 ConsecutiveSuccesses:0 ConsecutiveFailures:84}
RUNNING
will trip? {Requests:85 TotalSuccesses:0 TotalFailures:85 ConsecutiveSuccesses:0 ConsecutiveFailures:85}
RUNNING
will trip? {Requests:86 TotalSuccesses:0 TotalFailures:86 ConsecutiveSuccesses:0 ConsecutiveFailures:86}
RUNNING
will trip? {Requests:87 TotalSuccesses:0 TotalFailures:87 ConsecutiveSuccesses:0 ConsecutiveFailures:87}
RUNNING
will trip? {Requests:88 TotalSuccesses:0 TotalFailures:88 ConsecutiveSuccesses:0 ConsecutiveFailures:88}
RUNNING
will trip? {Requests:89 TotalSuccesses:0 TotalFailures:89 ConsecutiveSuccesses:0 ConsecutiveFailures:89}
RUNNING
will trip? {Requests:90 TotalSuccesses:0 TotalFailures:90 ConsecutiveSuccesses:0 ConsecutiveFailures:90}
RUNNING
will trip? {Requests:91 TotalSuccesses:0 TotalFailures:91 ConsecutiveSuccesses:0 ConsecutiveFailures:91}
RUNNING
will trip? {Requests:92 TotalSuccesses:0 TotalFailures:92 ConsecutiveSuccesses:0 ConsecutiveFailures:92}
RUNNING
will trip? {Requests:93 TotalSuccesses:0 TotalFailures:93 ConsecutiveSuccesses:0 ConsecutiveFailures:93}
RUNNING
will trip? {Requests:94 TotalSuccesses:0 TotalFailures:94 ConsecutiveSuccesses:0 ConsecutiveFailures:94}
RUNNING
will trip? {Requests:95 TotalSuccesses:0 TotalFailures:95 ConsecutiveSuccesses:0 ConsecutiveFailures:95}
RUNNING
will trip? {Requests:96 TotalSuccesses:0 TotalFailures:96 ConsecutiveSuccesses:0 ConsecutiveFailures:96}
RUNNING
will trip? {Requests:97 TotalSuccesses:0 TotalFailures:97 ConsecutiveSuccesses:0 ConsecutiveFailures:97}
RUNNING
will trip? {Requests:98 TotalSuccesses:0 TotalFailures:98 ConsecutiveSuccesses:0 ConsecutiveFailures:98}
RUNNING
will trip? {Requests:99 TotalSuccesses:0 TotalFailures:99 ConsecutiveSuccesses:0 ConsecutiveFailures:99}
RUNNING
will trip? {Requests:100 TotalSuccesses:0 TotalFailures:100 ConsecutiveSuccesses:0 ConsecutiveFailures:100}
Circuit breaker sad state change from closed to open
Circuit breaker sad state change from open to half-open
RUNNING
Circuit breaker sad state change from half-open to open
Circuit breaker sad state change from open to half-open
RUNNING
Circuit breaker sad state change from half-open to open
^C

Why is it executing only once in half-open state?

[question/proposal] Monitoring

I want to collect metrics based on Counts struct.

Initially, I think that I can put my metrics on ReadyToTrip but it is called only onFailure.
Can we have a method that is called whatever the result success/failure in order to display the metrics for each Allow?

I can propose a PR if you want.

Does this really require go 1.12?

The go.mod file is set to work only with go 1.12. When building with go 1.11 I get errors around which version of Go is required. Is go 1.12 required? Can this limitation be removed from the go.mod?

May I request a new release with tag

Hi,

Thanks a lot for your library, it's really helpful!

When I check the release, the latest is 0.4.1, which was published in May 2019, but the latest merge was in Jan 2021, I can use go mod to get the latest commit change, however, when we request 3rd party library approval from my company, maybe it would not be approved, so may I request a new release with tag 0.4.2? Really appreciate it!

Exported type for errors

Hi, we have a use case where we need to check the returned error, and we need to be able to see if it's returned from the CB.

Can we open a PR with an exported error?

It will cause a deadlock when call breaker.Counts() method in the OnStateChange() method

When the OnStateChange method is trigered, I want to know the breaker counts, so i call breaker.Counts(), but I get a deadlock
The code is :

OnStateChange: func(name string, from gobreaker.State, to gobreaker.State) {
	// NOTICE:do not call breaker.Counts() in this method , it will cause a deadlock !!! 
	counts := breaker.Counts()
	logger.Infof("key: %s, breaker state has change, from %s to %s , the data --> %v", breaker.Name(), from.String(), to.String(), counts)
}

What method should I call when I want to know the counts number in OnStateChange method ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.