rubyist / circuitbreaker

Circuit Breakers in Go
MIT License
1.12k stars 108 forks source link

Breaker.Ready() has side effects #33

Open youngkin opened 8 years ago

youngkin commented 8 years ago

Calling Ready() on a half-open breaker will reset the breaker to open. I'm writing a test to better understand how Breaker behaves in a half-open state. I'm using Breaker.Ready() to detect when the Breaker transitions to half-open.

...
// Breaker trips to open
...

ready := cb.Ready()
fmt.Print("\nLet circuit transition to half-open\n\n")
for {
    if ready {
        break
    }
    time.Sleep(10 * time.Millisecond)
    ready = cb.Ready()
}

fmt.Printf("\nReady() == %v; Tripped == %v\n", ready, cb.Tripped())
fmt.Printf("Call Ready() again after it returns true, Ready() == %v; Tripped() == %v\n\n", 
               cb.Ready(), cb.Tripped())

When run it prints

Ready() == true; Tripped == true
Call Ready() again after it returns true, Ready() == false; Tripped() == true

Since Call() also invokes Ready(), using Ready() as I did above causes the subsequent call to Call() to fail since the circuit state is now open.

So, is there a way to test a Breaker to see if it's half-open without calling Ready()? Also, given Ready()'s side effects, perhaps it shouldn't be public?

UPDATE: After re-reading the README file I have a better understanding of the intended use of Ready() to allow the user to implement their own version of Call(). Even so, it would be nice to call out in the godoc that Ready() should not be used in conjunction with Call().