@@ -13,7 +13,6 @@ const DEFAULT_AUTO_RESUBSCRTBE: bool = true;
13
13
const DEFAULT_AUTO_REMONITOR : bool = true ;
14
14
const DEFAULT_KEEP_ALIVE : Option < Duration > = None ;
15
15
const DEFAULT_NO_DELAY : bool = true ;
16
- const DEFAULT_MAX_COMMAND_ATTEMPTS : usize = 3 ;
17
16
const DEFAULT_RETRY_ON_ERROR : bool = false ;
18
17
19
18
type Uri < ' a > = (
@@ -84,8 +83,6 @@ pub struct Config {
84
83
///
85
84
/// See [`TcpStream::set_nodelay`](https://docs.rs/tokio/latest/tokio/net/struct.TcpStream.html#method.set_nodelay)
86
85
pub no_delay : bool ,
87
- /// Maximum number of retry attempts to send a command to the Redis server (default `3`).
88
- pub max_command_attempts : usize ,
89
86
/// Defines the default strategy for retries on network error (default `false`):
90
87
/// * `true` - retry sending the command/batch of commands on network error
91
88
/// * `false` - do not retry sending the command/batch of commands on network error
@@ -99,6 +96,8 @@ pub struct Config {
99
96
/// * [`Client::send_and_forget`](crate::client::Client::send_and_forget)
100
97
/// * [`Client::send_batch`](crate::client::Client::send_batch)
101
98
pub retry_on_error : bool ,
99
+ /// Reconnection configuration (Constant, Linear or Exponential)
100
+ pub reconnection : ReconnectionConfig ,
102
101
}
103
102
104
103
impl Default for Config {
@@ -117,8 +116,8 @@ impl Default for Config {
117
116
connection_name : String :: from ( "" ) ,
118
117
keep_alive : DEFAULT_KEEP_ALIVE ,
119
118
no_delay : DEFAULT_NO_DELAY ,
120
- max_command_attempts : DEFAULT_MAX_COMMAND_ATTEMPTS ,
121
119
retry_on_error : DEFAULT_RETRY_ON_ERROR ,
120
+ reconnection : Default :: default ( ) ,
122
121
}
123
122
}
124
123
}
@@ -315,12 +314,6 @@ impl Config {
315
314
}
316
315
}
317
316
318
- if let Some ( max_command_attempts) = query. remove ( "max_command_attempts" ) {
319
- if let Ok ( max_command_attempts) = max_command_attempts. parse :: < usize > ( ) {
320
- config. max_command_attempts = max_command_attempts;
321
- }
322
- }
323
-
324
317
if let Some ( retry_on_error) = query. remove ( "retry_on_error" ) {
325
318
if let Ok ( retry_on_error) = retry_on_error. parse :: < bool > ( ) {
326
319
config. retry_on_error = retry_on_error;
@@ -583,19 +576,6 @@ impl ToString for Config {
583
576
s. push_str ( & format ! ( "no_delay={}" , self . no_delay) ) ;
584
577
}
585
578
586
- if self . max_command_attempts != DEFAULT_MAX_COMMAND_ATTEMPTS {
587
- if !query_separator {
588
- query_separator = true ;
589
- s. push ( '?' ) ;
590
- } else {
591
- s. push ( '&' ) ;
592
- }
593
- s. push_str ( & format ! (
594
- "max_command_attempts={}" ,
595
- self . max_command_attempts
596
- ) ) ;
597
- }
598
-
599
579
if self . retry_on_error != DEFAULT_RETRY_ON_ERROR {
600
580
if !query_separator {
601
581
query_separator = true ;
@@ -874,3 +854,111 @@ impl IntoConfig for Url {
874
854
Config :: from_uri ( self )
875
855
}
876
856
}
857
+
858
+ /// The type of reconnection policy to use. This will apply to every connection used by the client.
859
+ /// This code has been mostly inpisred by [fred ReconnectPolicy](https://docs.rs/fred/latest/fred/types/enum.ReconnectPolicy.html)
860
+ #[ derive( Debug , Clone ) ]
861
+ pub enum ReconnectionConfig {
862
+ /// Wait a constant amount of time between reconnection attempts, in ms.
863
+ Constant {
864
+ /// Maximum number of attemps, set `0` to retry forever.
865
+ max_attempts : u32 ,
866
+ /// Delay in ms to wait between reconnection attempts
867
+ delay : u32 ,
868
+ /// Add jitter in ms to each delay
869
+ jitter : u32 ,
870
+ } ,
871
+ /// Backoff reconnection attempts linearly, adding `delay` each time.
872
+ Linear {
873
+ /// Maximum number of attemps, set `0` to retry forever.
874
+ max_attempts : u32 ,
875
+ /// Maximum delay in ms
876
+ max_delay : u32 ,
877
+ /// Delay in ms to add to the total waiting time at each attemp
878
+ delay : u32 ,
879
+ /// Add jitter in ms to each delay
880
+ jitter : u32 ,
881
+ } ,
882
+ /// Backoff reconnection attempts exponentially, multiplying the last delay by `multiplicative_factor` each time.
883
+ /// see https://en.wikipedia.org/wiki/Exponential_backoff
884
+ Exponential {
885
+ /// Maximum number of attemps, set `0` to retry forever.
886
+ max_attempts : u32 ,
887
+ /// Minimum delay in ms
888
+ min_delay : u32 ,
889
+ /// Maximum delay in ms
890
+ max_delay : u32 ,
891
+ // multiplicative factor
892
+ multiplicative_factor : u32 ,
893
+ /// Add jitter in ms to each delay
894
+ jitter : u32 ,
895
+ } ,
896
+ }
897
+
898
+ /// The default amount of jitter when waiting to reconnect.
899
+ const DEFAULT_JITTER_MS : u32 = 100 ;
900
+ const DEFAULT_DELAY_MS : u32 = 1000 ;
901
+
902
+ impl Default for ReconnectionConfig {
903
+ fn default ( ) -> Self {
904
+ Self :: Constant {
905
+ max_attempts : 0 ,
906
+ delay : DEFAULT_DELAY_MS ,
907
+ jitter : DEFAULT_JITTER_MS ,
908
+ }
909
+ }
910
+ }
911
+
912
+ impl ReconnectionConfig {
913
+ /// Create a new reconnect policy with a constant backoff.
914
+ pub fn new_constant ( max_attempts : u32 , delay : u32 ) -> Self {
915
+ Self :: Constant {
916
+ max_attempts,
917
+ delay,
918
+ jitter : DEFAULT_JITTER_MS ,
919
+ }
920
+ }
921
+
922
+ /// Create a new reconnect policy with a linear backoff.
923
+ pub fn new_linear ( max_attempts : u32 , max_delay : u32 , delay : u32 ) -> Self {
924
+ Self :: Linear {
925
+ max_attempts,
926
+ max_delay,
927
+ delay,
928
+ jitter : DEFAULT_JITTER_MS ,
929
+ }
930
+ }
931
+
932
+ /// Create a new reconnect policy with an exponential backoff.
933
+ pub fn new_exponential (
934
+ max_attempts : u32 ,
935
+ min_delay : u32 ,
936
+ max_delay : u32 ,
937
+ multiplicative_factor : u32 ,
938
+ ) -> Self {
939
+ Self :: Exponential {
940
+ max_delay,
941
+ max_attempts,
942
+ min_delay,
943
+ multiplicative_factor,
944
+ jitter : DEFAULT_JITTER_MS ,
945
+ }
946
+ }
947
+
948
+ /// Set the amount of jitter to add to each reconnection delay.
949
+ ///
950
+ /// Default: 100 ms
951
+ pub fn set_jitter ( & mut self , jitter_ms : u32 ) {
952
+ match self {
953
+ Self :: Constant { ref mut jitter, .. } => {
954
+ * jitter = jitter_ms;
955
+ }
956
+ Self :: Linear { ref mut jitter, .. } => {
957
+ * jitter = jitter_ms;
958
+ }
959
+ Self :: Exponential { ref mut jitter, .. } => {
960
+ * jitter = jitter_ms;
961
+ }
962
+ }
963
+ }
964
+ }
0 commit comments