@@ -70,18 +70,12 @@ impl<Cl> RetryClient<Cl> {
70
70
}
71
71
}
72
72
73
- macro_rules! retry {
74
- ( $self: ident, $tag: literal, |$cluster : ident| $call: expr) => { {
73
+ macro_rules! retry_core {
74
+ ( $self: ident, $tag: literal, $call: expr) => { {
75
75
let stats = pd_stats( $tag) ;
76
76
let mut last_err = Ok ( ( ) ) ;
77
77
for _ in 0 ..LEADER_CHANGE_RETRY {
78
- // use the block here to drop the guard of the read lock,
79
- // otherwise `reconnect` will try to acquire the write lock and results in a deadlock
80
- let res = {
81
- let $cluster = & mut $self. cluster. write( ) . await . 0 ;
82
- let res = $call. await ;
83
- res
84
- } ;
78
+ let res = $call;
85
79
86
80
match stats. done( res) {
87
81
Ok ( r) => return Ok ( r) ,
@@ -103,6 +97,28 @@ macro_rules! retry {
103
97
} } ;
104
98
}
105
99
100
+ macro_rules! retry_mut {
101
+ ( $self: ident, $tag: literal, |$cluster: ident| $call: expr) => { {
102
+ retry_core!( $self, $tag, {
103
+ // use the block here to drop the guard of the lock,
104
+ // otherwise `reconnect` will try to acquire the write lock and results in a deadlock
105
+ let $cluster = & mut $self. cluster. write( ) . await . 0 ;
106
+ $call. await
107
+ } )
108
+ } } ;
109
+ }
110
+
111
+ macro_rules! retry {
112
+ ( $self: ident, $tag: literal, |$cluster: ident| $call: expr) => { {
113
+ retry_core!( $self, $tag, {
114
+ // use the block here to drop the guard of the lock,
115
+ // otherwise `reconnect` will try to acquire the write lock and results in a deadlock
116
+ let $cluster = & $self. cluster. read( ) . await . 0 ;
117
+ $call. await
118
+ } )
119
+ } } ;
120
+ }
121
+
106
122
impl RetryClient < Cluster > {
107
123
pub async fn connect (
108
124
endpoints : & [ String ] ,
@@ -127,7 +143,7 @@ impl RetryClientTrait for RetryClient<Cluster> {
127
143
// These get_* functions will try multiple times to make a request, reconnecting as necessary.
128
144
// It does not know about encoding. Caller should take care of it.
129
145
async fn get_region ( self : Arc < Self > , key : Vec < u8 > ) -> Result < RegionWithLeader > {
130
- retry ! ( self , "get_region" , |cluster| {
146
+ retry_mut ! ( self , "get_region" , |cluster| {
131
147
let key = key. clone( ) ;
132
148
async {
133
149
cluster
@@ -141,7 +157,7 @@ impl RetryClientTrait for RetryClient<Cluster> {
141
157
}
142
158
143
159
async fn get_region_by_id ( self : Arc < Self > , region_id : RegionId ) -> Result < RegionWithLeader > {
144
- retry ! ( self , "get_region_by_id" , |cluster| async {
160
+ retry_mut ! ( self , "get_region_by_id" , |cluster| async {
145
161
cluster
146
162
. get_region_by_id( region_id, self . timeout)
147
163
. await
@@ -152,7 +168,7 @@ impl RetryClientTrait for RetryClient<Cluster> {
152
168
}
153
169
154
170
async fn get_store ( self : Arc < Self > , id : StoreId ) -> Result < metapb:: Store > {
155
- retry ! ( self , "get_store" , |cluster| async {
171
+ retry_mut ! ( self , "get_store" , |cluster| async {
156
172
cluster
157
173
. get_store( id, self . timeout)
158
174
. await
@@ -161,7 +177,7 @@ impl RetryClientTrait for RetryClient<Cluster> {
161
177
}
162
178
163
179
async fn get_all_stores ( self : Arc < Self > ) -> Result < Vec < metapb:: Store > > {
164
- retry ! ( self , "get_all_stores" , |cluster| async {
180
+ retry_mut ! ( self , "get_all_stores" , |cluster| async {
165
181
cluster
166
182
. get_all_stores( self . timeout)
167
183
. await
@@ -174,7 +190,7 @@ impl RetryClientTrait for RetryClient<Cluster> {
174
190
}
175
191
176
192
async fn update_safepoint ( self : Arc < Self > , safepoint : u64 ) -> Result < bool > {
177
- retry ! ( self , "update_gc_safepoint" , |cluster| async {
193
+ retry_mut ! ( self , "update_gc_safepoint" , |cluster| async {
178
194
cluster
179
195
. update_safepoint( safepoint, self . timeout)
180
196
. await
@@ -257,7 +273,7 @@ mod test {
257
273
}
258
274
259
275
async fn retry_err ( client : Arc < MockClient > ) -> Result < ( ) > {
260
- retry ! ( client, "test" , |_c| ready( Err ( internal_err!( "whoops" ) ) ) )
276
+ retry_mut ! ( client, "test" , |_c| ready( Err ( internal_err!( "whoops" ) ) ) )
261
277
}
262
278
263
279
async fn retry_ok ( client : Arc < MockClient > ) -> Result < ( ) > {
@@ -310,7 +326,7 @@ mod test {
310
326
client : Arc < MockClient > ,
311
327
max_retries : Arc < AtomicUsize > ,
312
328
) -> Result < ( ) > {
313
- retry ! ( client, "test" , |c| {
329
+ retry_mut ! ( client, "test" , |c| {
314
330
c. fetch_add( 1 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
315
331
316
332
let max_retries = max_retries. fetch_sub( 1 , Ordering :: SeqCst ) - 1 ;
0 commit comments