Skip to content

Commit e9d0dcd

Browse files
Andrey Koshchiyekexium
andauthored
Custom backoff support for raw api (#350)
Signed-off-by: Andrey Koshchiy <roguepnz@gmail.com> Co-authored-by: ekexium <ekexium@fastmail.com>
1 parent b524bc6 commit e9d0dcd

File tree

1 file changed

+139
-14
lines changed

1 file changed

+139
-14
lines changed

src/raw/client.rs

Lines changed: 139 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,15 @@ impl<PdC: PdClient> Client<PdC> {
188188
/// # });
189189
/// ```
190190
pub async fn get(&self, key: impl Into<Key>) -> Result<Option<Value>> {
191+
self.get_opt(key, DEFAULT_REGION_BACKOFF).await
192+
}
193+
194+
/// Same as [`get`](Client::get) but with custom [`backoff`](crate::Backoff) strategy.
195+
pub async fn get_opt(&self, key: impl Into<Key>, backoff: Backoff) -> Result<Option<Value>> {
191196
debug!(self.logger, "invoking raw get request");
192197
let request = new_raw_get_request(key.into(), self.cf.clone());
193198
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), request)
194-
.retry_multi_region(DEFAULT_REGION_BACKOFF)
199+
.retry_multi_region(backoff)
195200
.merge(CollectSingle)
196201
.post_process_default()
197202
.plan();
@@ -219,11 +224,20 @@ impl<PdC: PdClient> Client<PdC> {
219224
pub async fn batch_get(
220225
&self,
221226
keys: impl IntoIterator<Item = impl Into<Key>>,
227+
) -> Result<Vec<KvPair>> {
228+
self.batch_get_opt(keys, DEFAULT_REGION_BACKOFF).await
229+
}
230+
231+
/// Same as [`batch_get`](Client::batch_get) but with custom [`backoff`](crate::Backoff) strategy.
232+
pub async fn batch_get_opt(
233+
&self,
234+
keys: impl IntoIterator<Item = impl Into<Key>>,
235+
backoff: Backoff,
222236
) -> Result<Vec<KvPair>> {
223237
debug!(self.logger, "invoking raw batch_get request");
224238
let request = new_raw_batch_get_request(keys.into_iter().map(Into::into), self.cf.clone());
225239
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), request)
226-
.retry_multi_region(DEFAULT_REGION_BACKOFF)
240+
.retry_multi_region(backoff)
227241
.merge(Collect)
228242
.plan();
229243
plan.execute()
@@ -248,10 +262,20 @@ impl<PdC: PdClient> Client<PdC> {
248262
/// # });
249263
/// ```
250264
pub async fn put(&self, key: impl Into<Key>, value: impl Into<Value>) -> Result<()> {
265+
self.put_opt(key, value, DEFAULT_REGION_BACKOFF).await
266+
}
267+
268+
/// Same as [`put`](Client::put) but with custom [`backoff`](crate::Backoff) strategy.
269+
pub async fn put_opt(
270+
&self,
271+
key: impl Into<Key>,
272+
value: impl Into<Value>,
273+
backoff: Backoff,
274+
) -> Result<()> {
251275
debug!(self.logger, "invoking raw put request");
252276
let request = new_raw_put_request(key.into(), value.into(), self.cf.clone(), self.atomic);
253277
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), request)
254-
.retry_multi_region(DEFAULT_REGION_BACKOFF)
278+
.retry_multi_region(backoff)
255279
.merge(CollectSingle)
256280
.extract_error()
257281
.plan();
@@ -279,6 +303,15 @@ impl<PdC: PdClient> Client<PdC> {
279303
pub async fn batch_put(
280304
&self,
281305
pairs: impl IntoIterator<Item = impl Into<KvPair>>,
306+
) -> Result<()> {
307+
self.batch_put_opt(pairs, DEFAULT_REGION_BACKOFF).await
308+
}
309+
310+
/// Same as [`batch_put`](Client::batch_put) but with custom [`backoff`](crate::Backoff) strategy.
311+
pub async fn batch_put_opt(
312+
&self,
313+
pairs: impl IntoIterator<Item = impl Into<KvPair>>,
314+
backoff: Backoff,
282315
) -> Result<()> {
283316
debug!(self.logger, "invoking raw batch_put request");
284317
let request = new_raw_batch_put_request(
@@ -287,7 +320,7 @@ impl<PdC: PdClient> Client<PdC> {
287320
self.atomic,
288321
);
289322
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), request)
290-
.retry_multi_region(DEFAULT_REGION_BACKOFF)
323+
.retry_multi_region(backoff)
291324
.extract_error()
292325
.plan();
293326
plan.execute().await?;
@@ -312,10 +345,15 @@ impl<PdC: PdClient> Client<PdC> {
312345
/// # });
313346
/// ```
314347
pub async fn delete(&self, key: impl Into<Key>) -> Result<()> {
348+
self.delete_opt(key, DEFAULT_REGION_BACKOFF).await
349+
}
350+
351+
/// Same as [`delete`](Client::delete) but with custom [`backoff`](crate::Backoff) strategy.
352+
pub async fn delete_opt(&self, key: impl Into<Key>, backoff: Backoff) -> Result<()> {
315353
debug!(self.logger, "invoking raw delete request");
316354
let request = new_raw_delete_request(key.into(), self.cf.clone(), self.atomic);
317355
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), request)
318-
.retry_multi_region(DEFAULT_REGION_BACKOFF)
356+
.retry_multi_region(backoff)
319357
.merge(CollectSingle)
320358
.extract_error()
321359
.plan();
@@ -341,12 +379,21 @@ impl<PdC: PdClient> Client<PdC> {
341379
/// # });
342380
/// ```
343381
pub async fn batch_delete(&self, keys: impl IntoIterator<Item = impl Into<Key>>) -> Result<()> {
382+
self.batch_delete_opt(keys, DEFAULT_REGION_BACKOFF).await
383+
}
384+
385+
/// Same as [`batch_delete`](Client::batch_delete) but with custom [`backoff`](crate::Backoff) strategy.
386+
pub async fn batch_delete_opt(
387+
&self,
388+
keys: impl IntoIterator<Item = impl Into<Key>>,
389+
backoff: Backoff,
390+
) -> Result<()> {
344391
debug!(self.logger, "invoking raw batch_delete request");
345392
self.assert_non_atomic()?;
346393
let request =
347394
new_raw_batch_delete_request(keys.into_iter().map(Into::into), self.cf.clone());
348395
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), request)
349-
.retry_multi_region(DEFAULT_REGION_BACKOFF)
396+
.retry_multi_region(backoff)
350397
.extract_error()
351398
.plan();
352399
plan.execute().await?;
@@ -372,6 +419,7 @@ impl<PdC: PdClient> Client<PdC> {
372419
self.delete_range_opt(range, DEFAULT_REGION_BACKOFF).await
373420
}
374421

422+
/// Same as [`delete_range`](Client::delete_range) but with custom [`backoff`](crate::Backoff) strategy.
375423
pub async fn delete_range_opt(
376424
&self,
377425
range: impl Into<BoundRange>,
@@ -408,8 +456,18 @@ impl<PdC: PdClient> Client<PdC> {
408456
/// # });
409457
/// ```
410458
pub async fn scan(&self, range: impl Into<BoundRange>, limit: u32) -> Result<Vec<KvPair>> {
459+
self.scan_opt(range, limit, DEFAULT_REGION_BACKOFF).await
460+
}
461+
462+
/// Same as [`scan`](Client::scan) but with custom [`backoff`](crate::Backoff) strategy.
463+
pub async fn scan_opt(
464+
&self,
465+
range: impl Into<BoundRange>,
466+
limit: u32,
467+
backoff: Backoff,
468+
) -> Result<Vec<KvPair>> {
411469
debug!(self.logger, "invoking raw scan request");
412-
self.scan_inner(range.into(), limit, false).await
470+
self.scan_inner(range.into(), limit, false, backoff).await
413471
}
414472

415473
/// Create a new 'scan' request that only returns the keys.
@@ -432,9 +490,20 @@ impl<PdC: PdClient> Client<PdC> {
432490
/// # });
433491
/// ```
434492
pub async fn scan_keys(&self, range: impl Into<BoundRange>, limit: u32) -> Result<Vec<Key>> {
493+
self.scan_keys_opt(range, limit, DEFAULT_REGION_BACKOFF)
494+
.await
495+
}
496+
497+
/// Same as [`scan_keys`](Client::scan_keys) but with custom [`backoff`](crate::Backoff) strategy.
498+
pub async fn scan_keys_opt(
499+
&self,
500+
range: impl Into<BoundRange>,
501+
limit: u32,
502+
backoff: Backoff,
503+
) -> Result<Vec<Key>> {
435504
debug!(self.logger, "invoking raw scan_keys request");
436505
Ok(self
437-
.scan_inner(range, limit, true)
506+
.scan_inner(range, limit, true, backoff)
438507
.await?
439508
.into_iter()
440509
.map(KvPair::into_key)
@@ -468,9 +537,21 @@ impl<PdC: PdClient> Client<PdC> {
468537
&self,
469538
ranges: impl IntoIterator<Item = impl Into<BoundRange>>,
470539
each_limit: u32,
540+
) -> Result<Vec<KvPair>> {
541+
self.batch_scan_opt(ranges, each_limit, DEFAULT_REGION_BACKOFF)
542+
.await
543+
}
544+
545+
/// Same as [`batch_scan`](Client::batch_scan) but with custom [`backoff`](crate::Backoff) strategy.
546+
pub async fn batch_scan_opt(
547+
&self,
548+
ranges: impl IntoIterator<Item = impl Into<BoundRange>>,
549+
each_limit: u32,
550+
backoff: Backoff,
471551
) -> Result<Vec<KvPair>> {
472552
debug!(self.logger, "invoking raw batch_scan request");
473-
self.batch_scan_inner(ranges, each_limit, false).await
553+
self.batch_scan_inner(ranges, each_limit, false, backoff)
554+
.await
474555
}
475556

476557
/// Create a new 'batch scan' request that only returns the keys.
@@ -500,10 +581,21 @@ impl<PdC: PdClient> Client<PdC> {
500581
&self,
501582
ranges: impl IntoIterator<Item = impl Into<BoundRange>>,
502583
each_limit: u32,
584+
) -> Result<Vec<Key>> {
585+
self.batch_scan_keys_opt(ranges, each_limit, DEFAULT_REGION_BACKOFF)
586+
.await
587+
}
588+
589+
/// Same as [`batch_scan_keys`](Client::batch_scan_keys) but with custom [`backoff`](crate::Backoff) strategy.
590+
pub async fn batch_scan_keys_opt(
591+
&self,
592+
ranges: impl IntoIterator<Item = impl Into<BoundRange>>,
593+
each_limit: u32,
594+
backoff: Backoff,
503595
) -> Result<Vec<Key>> {
504596
debug!(self.logger, "invoking raw batch_scan_keys request");
505597
Ok(self
506-
.batch_scan_inner(ranges, each_limit, true)
598+
.batch_scan_inner(ranges, each_limit, true, backoff)
507599
.await?
508600
.into_iter()
509601
.map(KvPair::into_key)
@@ -527,6 +619,18 @@ impl<PdC: PdClient> Client<PdC> {
527619
key: impl Into<Key>,
528620
previous_value: impl Into<Option<Value>>,
529621
new_value: impl Into<Value>,
622+
) -> Result<(Option<Value>, bool)> {
623+
self.compare_and_swap_opt(key, previous_value, new_value, DEFAULT_REGION_BACKOFF)
624+
.await
625+
}
626+
627+
/// Same as [`compare_and_swap`](Client::compare_and_swap) but with custom [`backoff`](crate::Backoff) strategy.
628+
pub async fn compare_and_swap_opt(
629+
&self,
630+
key: impl Into<Key>,
631+
previous_value: impl Into<Option<Value>>,
632+
new_value: impl Into<Value>,
633+
backoff: Backoff,
530634
) -> Result<(Option<Value>, bool)> {
531635
debug!(self.logger, "invoking raw compare_and_swap request");
532636
self.assert_atomic()?;
@@ -537,7 +641,7 @@ impl<PdC: PdClient> Client<PdC> {
537641
self.cf.clone(),
538642
);
539643
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), req)
540-
.retry_multi_region(DEFAULT_REGION_BACKOFF)
644+
.retry_multi_region(backoff)
541645
.merge(CollectSingle)
542646
.post_process_default()
543647
.plan();
@@ -550,6 +654,25 @@ impl<PdC: PdClient> Client<PdC> {
550654
copr_version_req: impl Into<String>,
551655
ranges: impl IntoIterator<Item = impl Into<BoundRange>>,
552656
request_builder: impl Fn(metapb::Region, Vec<Range<Key>>) -> Vec<u8> + Send + Sync + 'static,
657+
) -> Result<Vec<(Vec<u8>, Vec<Range<Key>>)>> {
658+
self.coprocessor_opt(
659+
copr_name,
660+
copr_version_req,
661+
ranges,
662+
request_builder,
663+
DEFAULT_REGION_BACKOFF,
664+
)
665+
.await
666+
}
667+
668+
/// Same as [`coprocessor`](Client::coprocessor) but with custom [`backoff`](crate::Backoff) strategy.
669+
pub async fn coprocessor_opt(
670+
&self,
671+
copr_name: impl Into<String>,
672+
copr_version_req: impl Into<String>,
673+
ranges: impl IntoIterator<Item = impl Into<BoundRange>>,
674+
request_builder: impl Fn(metapb::Region, Vec<Range<Key>>) -> Vec<u8> + Send + Sync + 'static,
675+
backoff: Backoff,
553676
) -> Result<Vec<(Vec<u8>, Vec<Range<Key>>)>> {
554677
let copr_version_req = copr_version_req.into();
555678
semver::VersionReq::from_str(&copr_version_req)?;
@@ -561,7 +684,7 @@ impl<PdC: PdClient> Client<PdC> {
561684
);
562685
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), req)
563686
.preserve_shard()
564-
.retry_multi_region(DEFAULT_REGION_BACKOFF)
687+
.retry_multi_region(backoff)
565688
.post_process_default()
566689
.plan();
567690
plan.execute().await
@@ -572,6 +695,7 @@ impl<PdC: PdClient> Client<PdC> {
572695
range: impl Into<BoundRange>,
573696
limit: u32,
574697
key_only: bool,
698+
backoff: Backoff,
575699
) -> Result<Vec<KvPair>> {
576700
if limit > MAX_RAW_KV_SCAN_LIMIT {
577701
return Err(Error::MaxScanLimitExceeded {
@@ -582,7 +706,7 @@ impl<PdC: PdClient> Client<PdC> {
582706

583707
let request = new_raw_scan_request(range.into(), limit, key_only, self.cf.clone());
584708
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), request)
585-
.retry_multi_region(DEFAULT_REGION_BACKOFF)
709+
.retry_multi_region(backoff)
586710
.merge(Collect)
587711
.plan();
588712
let res = plan.execute().await;
@@ -597,6 +721,7 @@ impl<PdC: PdClient> Client<PdC> {
597721
ranges: impl IntoIterator<Item = impl Into<BoundRange>>,
598722
each_limit: u32,
599723
key_only: bool,
724+
backoff: Backoff,
600725
) -> Result<Vec<KvPair>> {
601726
if each_limit > MAX_RAW_KV_SCAN_LIMIT {
602727
return Err(Error::MaxScanLimitExceeded {
@@ -612,7 +737,7 @@ impl<PdC: PdClient> Client<PdC> {
612737
self.cf.clone(),
613738
);
614739
let plan = crate::request::PlanBuilder::new(self.rpc.clone(), request)
615-
.retry_multi_region(DEFAULT_REGION_BACKOFF)
740+
.retry_multi_region(backoff)
616741
.merge(Collect)
617742
.plan();
618743
plan.execute().await

0 commit comments

Comments
 (0)