11use std:: ops:: { ControlFlow , Deref } ;
22use std:: str:: FromStr ;
33use std:: sync:: Arc ;
4- use std:: time:: { Duration , SystemTime } ;
4+ use std:: time:: { Duration , Instant , SystemTime } ;
55use std:: { fmt, slice} ;
66
77use base64:: prelude:: { BASE64_URL_SAFE_NO_PAD , Engine } ;
@@ -496,24 +496,24 @@ impl fmt::Debug for KeyAuthorization {
496496
497497/// A policy for retrying API requests
498498///
499- /// Refresh the order state from the server for `tries` times , waiting `delay` before the
500- /// first attempt and increasing the delay by a factor of `backoff` after each attempt.
499+ /// Refresh the order state repeatedly , waiting `delay` before the first attempt and increasing
500+ /// the delay by a factor of `backoff` after each attempt, until the `timeout` is reached .
501501#[ derive( Debug , Clone , Copy ) ]
502502pub struct RetryPolicy {
503- tries : u8 ,
504503 delay : Duration ,
505504 backoff : f32 ,
505+ timeout : Duration ,
506506}
507507
508508impl RetryPolicy {
509509 /// A constructor for the default `RetryPolicy`
510510 ///
511- /// Will retry 5 times with an initial delay of 250ms and a backoff factor of 2.0.
511+ /// Will retry for 5s with an initial delay of 250ms and a backoff factor of 2.0.
512512 pub const fn new ( ) -> Self {
513513 Self {
514- tries : 5 ,
515514 delay : Duration :: from_millis ( 250 ) ,
516515 backoff : 2.0 ,
516+ timeout : Duration :: from_secs ( 30 ) ,
517517 }
518518 }
519519
@@ -526,12 +526,6 @@ impl RetryPolicy {
526526 self
527527 }
528528
529- /// Set the number of retry attempts
530- pub const fn tries ( mut self , tries : u8 ) -> Self {
531- self . tries = tries;
532- self
533- }
534-
535529 /// Set the backoff factor
536530 ///
537531 /// The delay will be multiplied by this factor after each retry attempt.
@@ -540,11 +534,20 @@ impl RetryPolicy {
540534 self
541535 }
542536
537+ /// Set the timeout for retries
538+ ///
539+ /// After this duration has passed, no more retries will be attempted.
540+ pub const fn timeout ( mut self , timeout : Duration ) -> Self {
541+ self . timeout = timeout;
542+ self
543+ }
544+
543545 fn state ( & self ) -> RetryState {
544546 RetryState {
545- tries : self . tries ,
546547 delay : self . delay ,
547548 backoff : self . backoff ,
549+ timeout : self . timeout ,
550+ start : Instant :: now ( ) ,
548551 }
549552 }
550553}
@@ -556,28 +559,27 @@ impl Default for RetryPolicy {
556559}
557560
558561struct RetryState {
559- tries : u8 ,
560562 delay : Duration ,
561563 backoff : f32 ,
564+ timeout : Duration ,
565+ start : Instant ,
562566}
563567
564568impl RetryState {
565569 async fn wait ( & mut self , after : Option < SystemTime > ) -> ControlFlow < ( ) , ( ) > {
566- if self . tries == 0 {
570+ if self . start . elapsed ( ) > self . timeout {
567571 return ControlFlow :: Break ( ( ) ) ;
568572 }
569573
570574 if let Some ( after) = after {
571575 if let Ok ( delay) = after. duration_since ( SystemTime :: now ( ) ) {
572576 sleep ( delay) . await ;
573- self . tries -= 1 ;
574577 return ControlFlow :: Continue ( ( ) ) ;
575578 }
576579 }
577580
578581 sleep ( self . delay ) . await ;
579582 self . delay = self . delay . mul_f32 ( self . backoff ) ;
580- self . tries -= 1 ;
581583 ControlFlow :: Continue ( ( ) )
582584 }
583585}
0 commit comments