diff --git a/breaker.go b/breaker.go index f7f1285..767fadd 100644 --- a/breaker.go +++ b/breaker.go @@ -64,7 +64,7 @@ type EWMABreaker struct { // higher sample counts to avoid opening up on small hiccups. // // The failureThreshold is the failure rate above which the breaker should open (0.0-1.0). -func NewEWMABreaker(sampleCount int, failureThreshold float64) *EWMABreaker { +func NewEWMABreaker(sampleCount uint, failureThreshold float64) *EWMABreaker { e := &EWMABreaker{ // https://en.wikipedia.org/wiki/Exponential_smoothing decay: 2 / (float64(sampleCount)/2 + 1), diff --git a/hoglet.go b/hoglet.go index d1d3c39..856889f 100644 --- a/hoglet.go +++ b/hoglet.go @@ -10,7 +10,7 @@ import ( // Circuit wraps a function and behaves like a simple circuit and breaker: it opens when the wrapped function fails and // stops calling the wrapped function until it closes again, returning [ErrCircuitOpen] in the meantime. // -// A zero circuit will not panic, but wraps a noop. Use [NewCircuit] instead. +// A zero Circuit will panic, analogous to calling a nil function variable. Initialize with [NewCircuit]. type Circuit[IN, OUT any] struct { f BreakableFunc[IN, OUT] breaker Breaker @@ -47,8 +47,8 @@ type Breaker interface { // BreakableFunc is the type of the function wrapped by a Breaker. type BreakableFunc[IN, OUT any] func(context.Context, IN) (OUT, error) -// NewCircuit instantiates a new circuit breaker that wraps the given function. See [Circuit.Call] for calling semantics. -// A Circuit with a nil breaker will never open. +// NewCircuit instantiates a new [Circuit] that wraps the provided function. See [Circuit.Call] for calling semantics. +// A Circuit with a nil breaker is a noop wrapper around the provided function and will never open. func NewCircuit[IN, OUT any](f BreakableFunc[IN, OUT], breaker Breaker, opts ...Option) *Circuit[IN, OUT] { b := &Circuit[IN, OUT]{ f: f, @@ -126,10 +126,6 @@ func (c *Circuit[IN, OUT]) setOpenedAt(i int64) { // // Panics are observed as failures, but are not recovered (i.e.: they are "repanicked" instead). func (c *Circuit[IN, OUT]) Call(ctx context.Context, in IN) (out OUT, err error) { - if c.f == nil { - return out, nil - } - obs := c.observerForCall() if obs == nil { return out, ErrCircuitOpen diff --git a/hoglet_test.go b/hoglet_test.go index d642e55..72f2d2c 100644 --- a/hoglet_test.go +++ b/hoglet_test.go @@ -34,7 +34,7 @@ func noop(ctx context.Context, in noopIn) (struct{}, error) { func BenchmarkHoglet_Do_EWMA(b *testing.B) { breaker := NewCircuit( - func(context.Context, struct{}) (struct{}, error) { return struct{}{}, nil }, + func(context.Context, struct{}) (out struct{}, err error) { return }, NewEWMABreaker(10, 0.9), ) @@ -52,7 +52,7 @@ func BenchmarkHoglet_Do_EWMA(b *testing.B) { func BenchmarkHoglet_Do_SlidingWindow(b *testing.B) { breaker := NewCircuit( - func(context.Context, struct{}) (struct{}, error) { return struct{}{}, nil }, + func(context.Context, struct{}) (out struct{}, err error) { return }, NewSlidingWindowBreaker(10*time.Second, 0.9), ) @@ -68,12 +68,6 @@ func BenchmarkHoglet_Do_SlidingWindow(b *testing.B) { }) } -func TestBreaker_zero_value_does_not_panic(t *testing.T) { - b := &Circuit[struct{}, struct{}]{} - _, err := b.Call(context.Background(), struct{}{}) - assert.NoError(t, err) -} - func TestBreaker_nil_breaker_does_not_open(t *testing.T) { b := NewCircuit(noop, nil) _, err := b.Call(context.Background(), noopInFailure)