Merge pull request #281 from micro/retry
retry only on timeout or internal server error
This commit is contained in:
		| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user