mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-14 02:10:00 +08:00
feat: support context in breaker methods (#4088)
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package breaker
|
package breaker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -36,12 +37,16 @@ type (
|
|||||||
// The caller needs to call promise.Accept() on success,
|
// The caller needs to call promise.Accept() on success,
|
||||||
// or call promise.Reject() on failure.
|
// or call promise.Reject() on failure.
|
||||||
Allow() (Promise, error)
|
Allow() (Promise, error)
|
||||||
|
// AllowCtx checks if the request is allowed when ctx isn't done.
|
||||||
|
AllowCtx(ctx context.Context) (Promise, error)
|
||||||
|
|
||||||
// Do runs the given request if the Breaker accepts it.
|
// Do runs the given request if the Breaker accepts it.
|
||||||
// Do returns an error instantly if the Breaker rejects the request.
|
// Do returns an error instantly if the Breaker rejects the request.
|
||||||
// If a panic occurs in the request, the Breaker handles it as an error
|
// If a panic occurs in the request, the Breaker handles it as an error
|
||||||
// and causes the same panic again.
|
// and causes the same panic again.
|
||||||
Do(req func() error) error
|
Do(req func() error) error
|
||||||
|
// DoCtx runs the given request if the Breaker accepts it when ctx isn't done.
|
||||||
|
DoCtx(ctx context.Context, req func() error) error
|
||||||
|
|
||||||
// DoWithAcceptable runs the given request if the Breaker accepts it.
|
// DoWithAcceptable runs the given request if the Breaker accepts it.
|
||||||
// DoWithAcceptable returns an error instantly if the Breaker rejects the request.
|
// DoWithAcceptable returns an error instantly if the Breaker rejects the request.
|
||||||
@@ -49,12 +54,16 @@ type (
|
|||||||
// and causes the same panic again.
|
// and causes the same panic again.
|
||||||
// acceptable checks if it's a successful call, even if the error is not nil.
|
// acceptable checks if it's a successful call, even if the error is not nil.
|
||||||
DoWithAcceptable(req func() error, acceptable Acceptable) error
|
DoWithAcceptable(req func() error, acceptable Acceptable) error
|
||||||
|
// DoWithAcceptableCtx runs the given request if the Breaker accepts it when ctx isn't done.
|
||||||
|
DoWithAcceptableCtx(ctx context.Context, req func() error, acceptable Acceptable) error
|
||||||
|
|
||||||
// DoWithFallback runs the given request if the Breaker accepts it.
|
// DoWithFallback runs the given request if the Breaker accepts it.
|
||||||
// DoWithFallback runs the fallback if the Breaker rejects the request.
|
// DoWithFallback runs the fallback if the Breaker rejects the request.
|
||||||
// If a panic occurs in the request, the Breaker handles it as an error
|
// If a panic occurs in the request, the Breaker handles it as an error
|
||||||
// and causes the same panic again.
|
// and causes the same panic again.
|
||||||
DoWithFallback(req func() error, fallback Fallback) error
|
DoWithFallback(req func() error, fallback Fallback) error
|
||||||
|
// DoWithFallbackCtx runs the given request if the Breaker accepts it when ctx isn't done.
|
||||||
|
DoWithFallbackCtx(ctx context.Context, req func() error, fallback Fallback) error
|
||||||
|
|
||||||
// DoWithFallbackAcceptable runs the given request if the Breaker accepts it.
|
// DoWithFallbackAcceptable runs the given request if the Breaker accepts it.
|
||||||
// DoWithFallbackAcceptable runs the fallback if the Breaker rejects the request.
|
// DoWithFallbackAcceptable runs the fallback if the Breaker rejects the request.
|
||||||
@@ -62,6 +71,9 @@ type (
|
|||||||
// and causes the same panic again.
|
// and causes the same panic again.
|
||||||
// acceptable checks if it's a successful call, even if the error is not nil.
|
// acceptable checks if it's a successful call, even if the error is not nil.
|
||||||
DoWithFallbackAcceptable(req func() error, fallback Fallback, acceptable Acceptable) error
|
DoWithFallbackAcceptable(req func() error, fallback Fallback, acceptable Acceptable) error
|
||||||
|
// DoWithFallbackAcceptableCtx runs the given request if the Breaker accepts it when ctx isn't done.
|
||||||
|
DoWithFallbackAcceptableCtx(ctx context.Context, req func() error, fallback Fallback,
|
||||||
|
acceptable Acceptable) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback is the func to be called if the request is rejected.
|
// Fallback is the func to be called if the request is rejected.
|
||||||
@@ -118,23 +130,71 @@ func (cb *circuitBreaker) Allow() (Promise, error) {
|
|||||||
return cb.throttle.allow()
|
return cb.throttle.allow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cb *circuitBreaker) AllowCtx(ctx context.Context) (Promise, error) {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
default:
|
||||||
|
return cb.Allow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (cb *circuitBreaker) Do(req func() error) error {
|
func (cb *circuitBreaker) Do(req func() error) error {
|
||||||
return cb.throttle.doReq(req, nil, defaultAcceptable)
|
return cb.throttle.doReq(req, nil, defaultAcceptable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cb *circuitBreaker) DoCtx(ctx context.Context, req func() error) error {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
default:
|
||||||
|
return cb.Do(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (cb *circuitBreaker) DoWithAcceptable(req func() error, acceptable Acceptable) error {
|
func (cb *circuitBreaker) DoWithAcceptable(req func() error, acceptable Acceptable) error {
|
||||||
return cb.throttle.doReq(req, nil, acceptable)
|
return cb.throttle.doReq(req, nil, acceptable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cb *circuitBreaker) DoWithAcceptableCtx(ctx context.Context, req func() error,
|
||||||
|
acceptable Acceptable) error {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
default:
|
||||||
|
return cb.DoWithAcceptable(req, acceptable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (cb *circuitBreaker) DoWithFallback(req func() error, fallback Fallback) error {
|
func (cb *circuitBreaker) DoWithFallback(req func() error, fallback Fallback) error {
|
||||||
return cb.throttle.doReq(req, fallback, defaultAcceptable)
|
return cb.throttle.doReq(req, fallback, defaultAcceptable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cb *circuitBreaker) DoWithFallbackCtx(ctx context.Context, req func() error,
|
||||||
|
fallback Fallback) error {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
default:
|
||||||
|
return cb.DoWithFallback(req, fallback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (cb *circuitBreaker) DoWithFallbackAcceptable(req func() error, fallback Fallback,
|
func (cb *circuitBreaker) DoWithFallbackAcceptable(req func() error, fallback Fallback,
|
||||||
acceptable Acceptable) error {
|
acceptable Acceptable) error {
|
||||||
return cb.throttle.doReq(req, fallback, acceptable)
|
return cb.throttle.doReq(req, fallback, acceptable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cb *circuitBreaker) DoWithFallbackAcceptableCtx(ctx context.Context, req func() error,
|
||||||
|
fallback Fallback, acceptable Acceptable) error {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
default:
|
||||||
|
return cb.DoWithFallbackAcceptable(req, fallback, acceptable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (cb *circuitBreaker) Name() string {
|
func (cb *circuitBreaker) Name() string {
|
||||||
return cb.name
|
return cb.name
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package breaker
|
package breaker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/zeromicro/go-zero/core/stat"
|
"github.com/zeromicro/go-zero/core/stat"
|
||||||
@@ -16,10 +18,242 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCircuitBreaker_Allow(t *testing.T) {
|
func TestCircuitBreaker_Allow(t *testing.T) {
|
||||||
b := NewBreaker()
|
t.Run("allow", func(t *testing.T) {
|
||||||
assert.True(t, len(b.Name()) > 0)
|
b := NewBreaker()
|
||||||
_, err := b.Allow()
|
assert.True(t, len(b.Name()) > 0)
|
||||||
assert.Nil(t, err)
|
_, err := b.Allow()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("allow with ctx", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
_, err := b.AllowCtx(context.Background())
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("allow with ctx timeout", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Microsecond)
|
||||||
|
defer cancel()
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
_, err := b.AllowCtx(ctx)
|
||||||
|
assert.ErrorIs(t, err, context.DeadlineExceeded)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("allow with ctx cancel", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
|
cancel()
|
||||||
|
_, err := b.AllowCtx(ctx)
|
||||||
|
assert.ErrorIs(t, err, context.Canceled)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCircuitBreaker_Do(t *testing.T) {
|
||||||
|
t.Run("do", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
err := b.Do(func() error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("do with ctx", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
err := b.DoCtx(context.Background(), func() error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("do with ctx timeout", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Microsecond)
|
||||||
|
defer cancel()
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
err := b.DoCtx(ctx, func() error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
assert.ErrorIs(t, err, context.DeadlineExceeded)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("do with ctx cancel", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
|
cancel()
|
||||||
|
err := b.DoCtx(ctx, func() error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
assert.ErrorIs(t, err, context.Canceled)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCircuitBreaker_DoWithAcceptable(t *testing.T) {
|
||||||
|
t.Run("doWithAcceptable", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
err := b.DoWithAcceptable(func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("doWithAcceptable with ctx", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
err := b.DoWithAcceptableCtx(context.Background(), func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("doWithAcceptable with ctx timeout", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Microsecond)
|
||||||
|
defer cancel()
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
err := b.DoWithAcceptableCtx(ctx, func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.ErrorIs(t, err, context.DeadlineExceeded)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("doWithAcceptable with ctx cancel", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
|
cancel()
|
||||||
|
err := b.DoWithAcceptableCtx(ctx, func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.ErrorIs(t, err, context.Canceled)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCircuitBreaker_DoWithFallback(t *testing.T) {
|
||||||
|
t.Run("doWithFallback", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
err := b.DoWithFallback(func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) error {
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("doWithFallback with ctx", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
err := b.DoWithFallbackCtx(context.Background(), func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) error {
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("doWithFallback with ctx timeout", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Microsecond)
|
||||||
|
defer cancel()
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
err := b.DoWithFallbackCtx(ctx, func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) error {
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
assert.ErrorIs(t, err, context.DeadlineExceeded)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("doWithFallback with ctx cancel", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
|
cancel()
|
||||||
|
err := b.DoWithFallbackCtx(ctx, func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) error {
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
assert.ErrorIs(t, err, context.Canceled)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCircuitBreaker_DoWithFallbackAcceptable(t *testing.T) {
|
||||||
|
t.Run("doWithFallbackAcceptable", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
err := b.DoWithFallbackAcceptable(func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) error {
|
||||||
|
return err
|
||||||
|
}, func(err error) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("doWithFallbackAcceptable with ctx", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
err := b.DoWithFallbackAcceptableCtx(context.Background(), func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) error {
|
||||||
|
return err
|
||||||
|
}, func(err error) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("doWithFallbackAcceptable with ctx timeout", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Microsecond)
|
||||||
|
defer cancel()
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
err := b.DoWithFallbackAcceptableCtx(ctx, func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) error {
|
||||||
|
return err
|
||||||
|
}, func(err error) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.ErrorIs(t, err, context.DeadlineExceeded)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("doWithFallbackAcceptable with ctx cancel", func(t *testing.T) {
|
||||||
|
b := NewBreaker()
|
||||||
|
assert.True(t, len(b.Name()) > 0)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
|
cancel()
|
||||||
|
err := b.DoWithFallbackAcceptableCtx(ctx, func() error {
|
||||||
|
return nil
|
||||||
|
}, func(err error) error {
|
||||||
|
return err
|
||||||
|
}, func(err error) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.ErrorIs(t, err, context.Canceled)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLogReason(t *testing.T) {
|
func TestLogReason(t *testing.T) {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package breaker
|
package breaker
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
const nopBreakerName = "nopBreaker"
|
const nopBreakerName = "nopBreaker"
|
||||||
|
|
||||||
type nopBreaker struct{}
|
type nopBreaker struct{}
|
||||||
@@ -17,22 +19,43 @@ func (b nopBreaker) Allow() (Promise, error) {
|
|||||||
return nopPromise{}, nil
|
return nopPromise{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b nopBreaker) AllowCtx(_ context.Context) (Promise, error) {
|
||||||
|
return nopPromise{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (b nopBreaker) Do(req func() error) error {
|
func (b nopBreaker) Do(req func() error) error {
|
||||||
return req()
|
return req()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b nopBreaker) DoCtx(_ context.Context, req func() error) error {
|
||||||
|
return req()
|
||||||
|
}
|
||||||
|
|
||||||
func (b nopBreaker) DoWithAcceptable(req func() error, _ Acceptable) error {
|
func (b nopBreaker) DoWithAcceptable(req func() error, _ Acceptable) error {
|
||||||
return req()
|
return req()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b nopBreaker) DoWithAcceptableCtx(_ context.Context, req func() error, _ Acceptable) error {
|
||||||
|
return req()
|
||||||
|
}
|
||||||
|
|
||||||
func (b nopBreaker) DoWithFallback(req func() error, _ Fallback) error {
|
func (b nopBreaker) DoWithFallback(req func() error, _ Fallback) error {
|
||||||
return req()
|
return req()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b nopBreaker) DoWithFallbackCtx(_ context.Context, req func() error, _ Fallback) error {
|
||||||
|
return req()
|
||||||
|
}
|
||||||
|
|
||||||
func (b nopBreaker) DoWithFallbackAcceptable(req func() error, _ Fallback, _ Acceptable) error {
|
func (b nopBreaker) DoWithFallbackAcceptable(req func() error, _ Fallback, _ Acceptable) error {
|
||||||
return req()
|
return req()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b nopBreaker) DoWithFallbackAcceptableCtx(_ context.Context, req func() error,
|
||||||
|
_ Fallback, _ Acceptable) error {
|
||||||
|
return req()
|
||||||
|
}
|
||||||
|
|
||||||
type nopPromise struct{}
|
type nopPromise struct{}
|
||||||
|
|
||||||
func (p nopPromise) Accept() {
|
func (p nopPromise) Accept() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package breaker
|
package breaker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -12,6 +13,8 @@ func TestNopBreaker(t *testing.T) {
|
|||||||
assert.Equal(t, nopBreakerName, b.Name())
|
assert.Equal(t, nopBreakerName, b.Name())
|
||||||
p, err := b.Allow()
|
p, err := b.Allow()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
p, err = b.AllowCtx(context.Background())
|
||||||
|
assert.Nil(t, err)
|
||||||
p.Accept()
|
p.Accept()
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
p, err := b.Allow()
|
p, err := b.Allow()
|
||||||
@@ -21,18 +24,34 @@ func TestNopBreaker(t *testing.T) {
|
|||||||
assert.Nil(t, b.Do(func() error {
|
assert.Nil(t, b.Do(func() error {
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
|
assert.Nil(t, b.DoCtx(context.Background(), func() error {
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
assert.Nil(t, b.DoWithAcceptable(func() error {
|
assert.Nil(t, b.DoWithAcceptable(func() error {
|
||||||
return nil
|
return nil
|
||||||
}, defaultAcceptable))
|
}, defaultAcceptable))
|
||||||
|
assert.Nil(t, b.DoWithAcceptableCtx(context.Background(), func() error {
|
||||||
|
return nil
|
||||||
|
}, defaultAcceptable))
|
||||||
errDummy := errors.New("any")
|
errDummy := errors.New("any")
|
||||||
assert.Equal(t, errDummy, b.DoWithFallback(func() error {
|
assert.Equal(t, errDummy, b.DoWithFallback(func() error {
|
||||||
return errDummy
|
return errDummy
|
||||||
}, func(err error) error {
|
}, func(err error) error {
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
|
assert.Equal(t, errDummy, b.DoWithFallbackCtx(context.Background(), func() error {
|
||||||
|
return errDummy
|
||||||
|
}, func(err error) error {
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
assert.Equal(t, errDummy, b.DoWithFallbackAcceptable(func() error {
|
assert.Equal(t, errDummy, b.DoWithFallbackAcceptable(func() error {
|
||||||
return errDummy
|
return errDummy
|
||||||
}, func(err error) error {
|
}, func(err error) error {
|
||||||
return nil
|
return nil
|
||||||
}, defaultAcceptable))
|
}, defaultAcceptable))
|
||||||
|
assert.Equal(t, errDummy, b.DoWithFallbackAcceptableCtx(context.Background(), func() error {
|
||||||
|
return errDummy
|
||||||
|
}, func(err error) error {
|
||||||
|
return nil
|
||||||
|
}, defaultAcceptable))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -595,19 +595,40 @@ func (d *dropBreaker) Allow() (breaker.Promise, error) {
|
|||||||
return nil, errDummy
|
return nil, errDummy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *dropBreaker) AllowCtx(_ context.Context) (breaker.Promise, error) {
|
||||||
|
return nil, errDummy
|
||||||
|
}
|
||||||
|
|
||||||
func (d *dropBreaker) Do(_ func() error) error {
|
func (d *dropBreaker) Do(_ func() error) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *dropBreaker) DoCtx(_ context.Context, _ func() error) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *dropBreaker) DoWithAcceptable(_ func() error, _ breaker.Acceptable) error {
|
func (d *dropBreaker) DoWithAcceptable(_ func() error, _ breaker.Acceptable) error {
|
||||||
return errDummy
|
return errDummy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *dropBreaker) DoWithAcceptableCtx(_ context.Context, _ func() error, _ breaker.Acceptable) error {
|
||||||
|
return errDummy
|
||||||
|
}
|
||||||
|
|
||||||
func (d *dropBreaker) DoWithFallback(_ func() error, _ breaker.Fallback) error {
|
func (d *dropBreaker) DoWithFallback(_ func() error, _ breaker.Fallback) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *dropBreaker) DoWithFallbackCtx(_ context.Context, _ func() error, _ breaker.Fallback) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *dropBreaker) DoWithFallbackAcceptable(_ func() error, _ breaker.Fallback,
|
func (d *dropBreaker) DoWithFallbackAcceptable(_ func() error, _ breaker.Fallback,
|
||||||
_ breaker.Acceptable) error {
|
_ breaker.Acceptable) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *dropBreaker) DoWithFallbackAcceptableCtx(_ context.Context, _ func() error,
|
||||||
|
_ breaker.Fallback, _ breaker.Acceptable) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user