Adding the ability to specify a function to check if micro should retry a failed rpc call

This commit is contained in:
Scott Finlay 2016-11-03 10:45:31 +01:00
parent 2c65a38ba9
commit d7e4062a0e
4 changed files with 44 additions and 4 deletions

View File

@ -68,6 +68,8 @@ var (
DefaultClient Client = newRpcClient()
// DefaultBackoff is the default backoff function for retries
DefaultBackoff = exponentialBackoff
// DefaultCheckIfRetriable is the default check-for-retry function for retries
DefaultCheckIfRetriable = AlwaysRetry
// DefaultRetries is the default number of times a request is tried
DefaultRetries = 1
// DefaultRequestTimeout is the default request timeout

22
client/is_retriable.go Normal file
View File

@ -0,0 +1,22 @@
package client
import (
"github.com/micro/go-micro/errors"
)
type IsRetriableFunc func(err error) bool
// always retry on error
func AlwaysRetry(err error) bool {
return true
}
func Only500Errors(err error) bool {
errorData := errors.Parse(err.Error())
if(errorData.Code >= 500) {
return true
}
return false
}

View File

@ -43,6 +43,8 @@ type CallOptions struct {
// Backoff func
Backoff BackoffFunc
// Check if retriable func
CheckIfRetriable IsRetriableFunc
// Transport Dial Timeout
DialTimeout time.Duration
// Number of Call attempts
@ -74,6 +76,7 @@ func newOptions(options ...Option) Options {
Codecs: make(map[string]codec.NewCodec),
CallOptions: CallOptions{
Backoff: DefaultBackoff,
CheckIfRetriable: DefaultCheckIfRetriable,
Retries: DefaultRetries,
RequestTimeout: DefaultRequestTimeout,
DialTimeout: transport.DefaultDialTimeout,
@ -221,6 +224,14 @@ func WithBackoff(fn BackoffFunc) CallOption {
}
}
// WithCheckIfRetriable is a CallOption which overrides that which
// set in Options.CallOptions
func WithCheckIfRetriable(fn IsRetriableFunc) CallOption {
return func(o *CallOptions) {
o.CheckIfRetriable = fn
}
}
// WithRetries is a CallOption which overrides that which
// set in Options.CallOptions
func WithRetries(i int) CallOption {

View File

@ -299,6 +299,11 @@ func (r *rpcClient) Call(ctx context.Context, request Request, response interfac
if err == nil {
return nil
}
if !callOpts.CheckIfRetriable(err) {
return err
}
gerr = err
}
}