Merge pull request #281 from micro/retry

retry only on timeout or internal server error
This commit is contained in:
Asim Aslam 2018-07-22 17:52:12 +01:00 committed by GitHub
commit 8a778644cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 5 deletions

View File

@ -68,7 +68,7 @@ var (
// DefaultBackoff is the default backoff function for retries // DefaultBackoff is the default backoff function for retries
DefaultBackoff = exponentialBackoff DefaultBackoff = exponentialBackoff
// DefaultRetry is the default check-for-retry function for retries // DefaultRetry is the default check-for-retry function for retries
DefaultRetry = alwaysRetry DefaultRetry = RetryOnError
// DefaultRetries is the default number of times a request is tried // DefaultRetries is the default number of times a request is tried
DefaultRetries = 1 DefaultRetries = 1
// DefaultRequestTimeout is the default request timeout // DefaultRequestTimeout is the default request timeout

View File

@ -2,12 +2,34 @@ package client
import ( import (
"context" "context"
"github.com/micro/go-micro/errors"
) )
// note that returning either false or a non-nil error will result in the call not being retried // note that returning either false or a non-nil error will result in the call not being retried
type RetryFunc func(ctx context.Context, req Request, retryCount int, err error) (bool, error) type RetryFunc func(ctx context.Context, req Request, retryCount int, err error) (bool, error)
// always retry on error // RetryAlways always retry on error
func alwaysRetry(ctx context.Context, req Request, retryCount int, err error) (bool, error) { func RetryAlways(ctx context.Context, req Request, retryCount int, err error) (bool, error) {
return true, nil return true, nil
} }
// RetryOnError retries a request on a 500 or timeout error
func RetryOnError(ctx context.Context, req Request, retryCount int, err error) (bool, error) {
if err == nil {
return false, nil
}
e := errors.Parse(err.Error())
if e == nil {
return false, nil
}
switch e.Code {
// retry on timeout or internal server error
case 408, 500:
return true, nil
default:
return false, nil
}
}

View File

@ -2,10 +2,10 @@ package client
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"testing" "testing"
"github.com/micro/go-micro/errors"
"github.com/micro/go-micro/registry" "github.com/micro/go-micro/registry"
"github.com/micro/go-micro/registry/mock" "github.com/micro/go-micro/registry/mock"
"github.com/micro/go-micro/selector" "github.com/micro/go-micro/selector"
@ -69,7 +69,7 @@ func TestCallRetry(t *testing.T) {
return func(ctx context.Context, addr string, req Request, rsp interface{}, opts CallOptions) error { return func(ctx context.Context, addr string, req Request, rsp interface{}, opts CallOptions) error {
called++ called++
if called == 1 { if called == 1 {
return errors.New("retry request") return errors.InternalServerError("test.error", "retry request")
} }
// don't do the call // don't do the call