diff --git a/client/client.go b/client/client.go index 87cdad01..74ec51be 100644 --- a/client/client.go +++ b/client/client.go @@ -68,7 +68,7 @@ var ( // DefaultBackoff is the default backoff function for retries DefaultBackoff = exponentialBackoff // 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 = 1 // DefaultRequestTimeout is the default request timeout diff --git a/client/retry.go b/client/retry.go index c094b4ea..46466d48 100644 --- a/client/retry.go +++ b/client/retry.go @@ -2,12 +2,34 @@ package client import ( "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 type RetryFunc func(ctx context.Context, req Request, retryCount int, err error) (bool, error) -// always retry on error -func alwaysRetry(ctx context.Context, req Request, retryCount int, err error) (bool, error) { +// RetryAlways always retry on error +func RetryAlways(ctx context.Context, req Request, retryCount int, err error) (bool, error) { 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 + } +} diff --git a/client/rpc_client_test.go b/client/rpc_client_test.go index fde49ffc..6bafbdf5 100644 --- a/client/rpc_client_test.go +++ b/client/rpc_client_test.go @@ -2,10 +2,10 @@ package client import ( "context" - "errors" "fmt" "testing" + "github.com/micro/go-micro/errors" "github.com/micro/go-micro/registry" "github.com/micro/go-micro/registry/mock" "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 { called++ if called == 1 { - return errors.New("retry request") + return errors.InternalServerError("test.error", "retry request") } // don't do the call