-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
retry_policy.h
139 lines (116 loc) · 5.37 KB
/
retry_policy.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#ifndef BRPC_RETRY_POLICY_H
#define BRPC_RETRY_POLICY_H
#include "brpc/controller.h"
namespace brpc {
// Inherit this class to customize when the RPC should be retried.
class RetryPolicy {
public:
virtual ~RetryPolicy() = default;
// Returns true if the RPC represented by `controller' should be retried.
// [Example]
// By default, HTTP errors are not retried, but you need to retry
// HTTP_STATUS_FORBIDDEN in your app. You can implement the RetryPolicy
// as follows:
//
// class MyRetryPolicy : public brpc::RetryPolicy {
// public:
// bool DoRetry(const brpc::Controller* cntl) const {
// if (cntl->ErrorCode() == 0) { // don't retry successful RPC
// return false;
// }
// if (cntl->ErrorCode() == brpc::EHTTP && // http errors
// cntl->http_response().status_code() == brpc::HTTP_STATUS_FORBIDDEN) {
// return true;
// }
// // Leave other cases to default.
// return brpc::DefaultRetryPolicy()->DoRetry(cntl);
// }
// };
//
// You can retry unqualified responses even if the RPC was successful
// class MyRetryPolicy : public brpc::RetryPolicy {
// public:
// bool DoRetry(const brpc::Controller* cntl) const {
// if (cntl->ErrorCode() == 0) { // successful RPC
// if (!is_qualified(cntl->response())) {
// cntl->response()->Clear(); // reset the response
// return true;
// }
// return false;
// }
// // Leave other cases to default.
// return brpc::DefaultRetryPolicy()->DoRetry(cntl);
// }
// };
virtual bool DoRetry(const Controller* controller) const = 0;
// ^
// don't forget the const modifier
// Returns the backoff time in milliseconds before every retry.
virtual int32_t GetBackoffTimeMs(const Controller* controller) const { return 0; }
// ^
// don't forget the const modifier
// Returns true if enable retry backoff in pthread, otherwise returns false.
virtual bool CanRetryBackoffInPthread() const { return false; }
// ^
// don't forget the const modifier
};
// Get the RetryPolicy used by brpc.
const RetryPolicy* DefaultRetryPolicy();
class RpcRetryPolicy : public RetryPolicy {
public:
bool DoRetry(const Controller* controller) const override;
};
class RpcRetryPolicyWithFixedBackoff : public RpcRetryPolicy {
public:
RpcRetryPolicyWithFixedBackoff(int32_t backoff_time_ms,
int32_t no_backoff_remaining_rpc_time_ms,
bool retry_backoff_in_pthread)
: _backoff_time_ms(backoff_time_ms)
, _no_backoff_remaining_rpc_time_ms(no_backoff_remaining_rpc_time_ms)
, _retry_backoff_in_pthread(retry_backoff_in_pthread) {}
int32_t GetBackoffTimeMs(const Controller* controller) const override;
bool CanRetryBackoffInPthread() const override { return _retry_backoff_in_pthread; }
private:
int32_t _backoff_time_ms;
// If remaining rpc time is less than `_no_backoff_remaining_rpc_time', no backoff.
int32_t _no_backoff_remaining_rpc_time_ms;
bool _retry_backoff_in_pthread;
};
class RpcRetryPolicyWithJitteredBackoff : public RpcRetryPolicy {
public:
RpcRetryPolicyWithJitteredBackoff(int32_t min_backoff_time_ms,
int32_t max_backoff_time_ms,
int32_t no_backoff_remaining_rpc_time_ms,
bool retry_backoff_in_pthread)
: _min_backoff_time_ms(min_backoff_time_ms)
, _max_backoff_time_ms(max_backoff_time_ms)
, _no_backoff_remaining_rpc_time_ms(no_backoff_remaining_rpc_time_ms)
, _retry_backoff_in_pthread(retry_backoff_in_pthread) {}
int32_t GetBackoffTimeMs(const Controller* controller) const override;
bool CanRetryBackoffInPthread() const override { return _retry_backoff_in_pthread; }
private:
// Generate jittered backoff time between [_min_backoff_ms, _max_backoff_ms].
int32_t _min_backoff_time_ms;
int32_t _max_backoff_time_ms;
// If remaining rpc time is less than `_no_backoff_remaining_rpc_time', no backoff.
int32_t _no_backoff_remaining_rpc_time_ms;
bool _retry_backoff_in_pthread;
};
} // namespace brpc
#endif // BRPC_RETRY_POLICY_H