diff --git a/client/backoff.go b/client/backoff.go index d548b724..0aed7c60 100644 --- a/client/backoff.go +++ b/client/backoff.go @@ -2,7 +2,6 @@ package client import ( "context" - "math" "time" "go.unistack.org/micro/v3/util/backoff" @@ -11,20 +10,6 @@ import ( // BackoffFunc is the backoff call func type BackoffFunc func(ctx context.Context, req Request, attempts int) (time.Duration, error) -// BackoffExp using exponential backoff func -func BackoffExp(_ context.Context, _ Request, attempts int) (time.Duration, error) { +func exponentialBackoff(ctx context.Context, req Request, attempts int) (time.Duration, error) { return backoff.Do(attempts), nil } - -// BackoffInterval specifies randomization interval for backoff func -func BackoffInterval(min time.Duration, max time.Duration) BackoffFunc { - return func(_ context.Context, _ Request, attempts int) (time.Duration, error) { - td := time.Duration(time.Duration(math.Pow(float64(attempts), math.E)) * time.Millisecond * 100) - if td < min { - return min, nil - } else if td > max { - return max, nil - } - return td, nil - } -} diff --git a/client/backoff_test.go b/client/backoff_test.go index 2ab854f7..5b9b60b8 100644 --- a/client/backoff_test.go +++ b/client/backoff_test.go @@ -22,7 +22,7 @@ func TestBackoff(t *testing.T) { } for i := 0; i < 5; i++ { - d, err := BackoffExp(context.TODO(), r, i) + d, err := exponentialBackoff(context.TODO(), r, i) if err != nil { t.Fatal(err) } diff --git a/client/client.go b/client/client.go index 71bedfd9..63cb4f85 100644 --- a/client/client.go +++ b/client/client.go @@ -14,8 +14,8 @@ var ( DefaultClient Client = NewClient() // DefaultContentType is the default content-type if not specified DefaultContentType = "application/json" - // DefaultBackoff is the default backoff function for retries (minimum 10 millisecond and maximum 5 second) - DefaultBackoff = BackoffInterval(10*time.Millisecond, 5*time.Second) + // DefaultBackoff is the default backoff function for retries + DefaultBackoff = exponentialBackoff // DefaultRetry is the default check-for-retry function for retries DefaultRetry = RetryNever // DefaultRetries is the default number of times a request is tried diff --git a/client/retry.go b/client/retry.go index a218b3fe..40272fd2 100644 --- a/client/retry.go +++ b/client/retry.go @@ -19,32 +19,18 @@ func RetryNever(ctx context.Context, req Request, retryCount int, err error) (bo return false, nil } -// RetryOnError retries a request on a 500 or 408 (timeout) error +// RetryOnError retries a request on a 500 or timeout error func RetryOnError(_ context.Context, _ Request, _ int, err error) (bool, error) { if err == nil { return false, nil } + me := errors.FromError(err) switch me.Code { // retry on timeout or internal server error case 408, 500: return true, nil } + return false, nil } - -// RetryOnErrors retries a request on specified error codes -func RetryOnErrors(codes ...int32) RetryFunc { - return func(_ context.Context, _ Request, _ int, err error) (bool, error) { - if err == nil { - return false, nil - } - me := errors.FromError(err) - for _, code := range codes { - if me.Code == code { - return true, nil - } - } - return false, nil - } -} diff --git a/router/context.go b/router/context.go new file mode 100644 index 00000000..2f156cfc --- /dev/null +++ b/router/context.go @@ -0,0 +1,34 @@ +package router + +import ( + "context" +) + +type routerKey struct{} + +// FromContext get router from context +func FromContext(ctx context.Context) (Router, bool) { + if ctx == nil { + return nil, false + } + c, ok := ctx.Value(routerKey{}).(Router) + return c, ok +} + +// NewContext put router in context +func NewContext(ctx context.Context, c Router) context.Context { + if ctx == nil { + ctx = context.Background() + } + return context.WithValue(ctx, routerKey{}, c) +} + +// SetOption returns a function to setup a context with given value +func SetOption(k, v interface{}) Option { + return func(o *Options) { + if o.Context == nil { + o.Context = context.Background() + } + o.Context = context.WithValue(o.Context, k, v) + } +} diff --git a/util/jitter/random.go b/util/jitter/random.go index c3caa5d3..eb03b29f 100644 --- a/util/jitter/random.go +++ b/util/jitter/random.go @@ -13,3 +13,8 @@ func Random(d time.Duration) time.Duration { v := rng.Float64() * float64(d.Nanoseconds()) return time.Duration(v) } + +func RandomInterval(min, max time.Duration) time.Duration { + var rng rand.Rand + return time.Duration(rng.Int63n(max.Nanoseconds()-min.Nanoseconds())+min.Nanoseconds()) * time.Nanosecond +}