9
9
10
10
"google.golang.org/grpc"
11
11
"google.golang.org/grpc/codes"
12
+ "google.golang.org/grpc/status"
12
13
)
13
14
14
15
var (
@@ -22,11 +23,11 @@ var (
22
23
max : 0 , // disabled
23
24
perCallTimeout : 0 , // disabled
24
25
includeHeader : true ,
25
- codes : DefaultRetriableCodes ,
26
26
backoffFunc : BackoffLinearWithJitter (50 * time .Millisecond /*jitter*/ , 0.10 ),
27
27
onRetryCallback : OnRetryCallback (func (ctx context.Context , attempt uint , err error ) {
28
28
logTrace (ctx , "grpc_retry attempt: %d, backoff for %v" , attempt , err )
29
29
}),
30
+ retriableFunc : newRetriableFuncForCodes (DefaultRetriableCodes ),
30
31
}
31
32
)
32
33
@@ -41,6 +42,9 @@ type BackoffFunc func(ctx context.Context, attempt uint) time.Duration
41
42
// OnRetryCallback is the type of function called when a retry occurs.
42
43
type OnRetryCallback func (ctx context.Context , attempt uint , err error )
43
44
45
+ // RetriableFunc denotes a family of functions that control which error should be retried.
46
+ type RetriableFunc func (err error ) bool
47
+
44
48
// Disable disables the retry behaviour on this call, or this interceptor.
45
49
//
46
50
// Its semantically the same to `WithMax`
@@ -78,7 +82,7 @@ func WithOnRetryCallback(fn OnRetryCallback) CallOption {
78
82
// You cannot automatically retry on Cancelled and Deadline, please use `WithPerRetryTimeout` for these.
79
83
func WithCodes (retryCodes ... codes.Code ) CallOption {
80
84
return CallOption {applyFunc : func (o * options ) {
81
- o .codes = retryCodes
85
+ o .retriableFunc = newRetriableFuncForCodes ( retryCodes )
82
86
}}
83
87
}
84
88
@@ -100,13 +104,20 @@ func WithPerRetryTimeout(timeout time.Duration) CallOption {
100
104
}}
101
105
}
102
106
107
+ // WithRetriable sets which error should be retried.
108
+ func WithRetriable (retriableFunc RetriableFunc ) CallOption {
109
+ return CallOption {applyFunc : func (o * options ) {
110
+ o .retriableFunc = retriableFunc
111
+ }}
112
+ }
113
+
103
114
type options struct {
104
115
max uint
105
116
perCallTimeout time.Duration
106
117
includeHeader bool
107
- codes []codes.Code
108
118
backoffFunc BackoffFunc
109
119
onRetryCallback OnRetryCallback
120
+ retriableFunc RetriableFunc
110
121
}
111
122
112
123
// CallOption is a grpc.CallOption that is local to grpc_retry.
@@ -137,3 +148,20 @@ func filterCallOptions(callOptions []grpc.CallOption) (grpcOptions []grpc.CallOp
137
148
}
138
149
return grpcOptions , retryOptions
139
150
}
151
+
152
+ // newRetriableFuncForCodes returns retriable function for specific Codes.
153
+ func newRetriableFuncForCodes (codes []codes.Code ) func (err error ) bool {
154
+ return func (err error ) bool {
155
+ errCode := status .Code (err )
156
+ if isContextError (err ) {
157
+ // context errors are not retriable based on user settings.
158
+ return false
159
+ }
160
+ for _ , code := range codes {
161
+ if code == errCode {
162
+ return true
163
+ }
164
+ }
165
+ return false
166
+ }
167
+ }
0 commit comments