11use crate :: auth:: { ClientCertificate , ConnectionTLSConfig } ;
22use crate :: errors:: { Error , Result } ;
3+ use backon:: ExponentialBuilder ;
34#[ cfg( feature = "unstable-bolt-protocol-impl-v2" ) ]
45use serde:: { Deserialize , Deserializer , Serialize } ;
56use std:: path:: Path ;
@@ -67,6 +68,87 @@ pub struct LiveConfig {
6768 pub ( crate ) fetch_size : usize ,
6869}
6970
71+ #[ derive( Debug , Clone , PartialEq ) ]
72+ pub struct BackoffConfig {
73+ pub ( crate ) multiplier : Option < f32 > ,
74+ pub ( crate ) min_delay_ms : Option < u64 > ,
75+ pub ( crate ) max_delay_ms : Option < u64 > ,
76+ pub ( crate ) total_delay_ms : Option < u64 > ,
77+ }
78+
79+ impl Default for BackoffConfig {
80+ fn default ( ) -> Self {
81+ BackoffConfig {
82+ multiplier : Some ( 2.0 ) ,
83+ min_delay_ms : Some ( 1 ) ,
84+ max_delay_ms : Some ( 10000 ) ,
85+ total_delay_ms : Some ( 60000 ) ,
86+ }
87+ }
88+ }
89+
90+ impl BackoffConfig {
91+ pub fn to_exponential_builder ( & self ) -> ExponentialBuilder {
92+ ExponentialBuilder :: new ( )
93+ . with_jitter ( )
94+ . with_factor ( self . multiplier . unwrap_or ( 2.0 ) )
95+ . without_max_times ( )
96+ . with_min_delay ( std:: time:: Duration :: from_millis (
97+ self . min_delay_ms . unwrap_or ( 1 ) ,
98+ ) )
99+ . with_max_delay ( std:: time:: Duration :: from_millis (
100+ self . max_delay_ms . unwrap_or ( 10_000 ) ,
101+ ) )
102+ . with_total_delay ( Some ( std:: time:: Duration :: from_millis (
103+ self . total_delay_ms . unwrap_or ( 60_000 ) ,
104+ ) ) )
105+ }
106+ }
107+
108+ #[ derive( Default ) ]
109+ pub struct BackoffConfigBuilder {
110+ multiplier : Option < f32 > ,
111+ min_delay_ms : Option < u64 > ,
112+ max_delay_ms : Option < u64 > ,
113+ total_delay_ms : Option < u64 > ,
114+ }
115+
116+ #[ allow( dead_code) ]
117+ impl BackoffConfigBuilder {
118+ pub fn new ( ) -> Self {
119+ Self :: default ( )
120+ }
121+
122+ pub fn with_multiplier ( mut self , multiplier : f32 ) -> Self {
123+ self . multiplier = Some ( multiplier) ;
124+ self
125+ }
126+
127+ pub fn with_min_delay_ms ( mut self , min_delay_ms : u64 ) -> Self {
128+ self . min_delay_ms = Some ( min_delay_ms) ;
129+ self
130+ }
131+
132+ pub fn with_max_delay_ms ( mut self , max_delay_ms : u64 ) -> Self {
133+ self . max_delay_ms = Some ( max_delay_ms) ;
134+ self
135+ }
136+
137+ pub fn with_total_delay_ms ( mut self , max_total_delay_ms : Option < u64 > ) -> Self {
138+ self . total_delay_ms = max_total_delay_ms;
139+ self
140+ }
141+
142+ pub fn build ( self ) -> BackoffConfig {
143+ BackoffConfig {
144+ multiplier : self . multiplier ,
145+ min_delay_ms : self . min_delay_ms ,
146+ max_delay_ms : self . max_delay_ms ,
147+ total_delay_ms : self . total_delay_ms ,
148+ }
149+ }
150+ }
151+
70152/// The configuration used to connect to the database, see [`crate::Graph::connect`].
71153#[ derive( Debug , Clone ) ]
72154pub struct Config {
@@ -77,6 +159,7 @@ pub struct Config {
77159 pub ( crate ) db : Option < Database > ,
78160 pub ( crate ) fetch_size : usize ,
79161 pub ( crate ) tls_config : ConnectionTLSConfig ,
162+ pub ( crate ) backoff : Option < BackoffConfig > ,
80163}
81164
82165impl Config {
@@ -97,6 +180,7 @@ pub struct ConfigBuilder {
97180 fetch_size : usize ,
98181 max_connections : usize ,
99182 tls_config : ConnectionTLSConfig ,
183+ backoff_config : Option < BackoffConfig > ,
100184}
101185
102186impl ConfigBuilder {
@@ -166,6 +250,11 @@ impl ConfigBuilder {
166250 self
167251 }
168252
253+ pub fn with_backoff ( mut self , backoff : Option < BackoffConfig > ) -> Self {
254+ self . backoff_config = backoff;
255+ self
256+ }
257+
169258 pub fn build ( self ) -> Result < Config > {
170259 if let ( Some ( uri) , Some ( user) , Some ( password) ) = ( self . uri , self . user , self . password ) {
171260 Ok ( Config {
@@ -176,6 +265,7 @@ impl ConfigBuilder {
176265 max_connections : self . max_connections ,
177266 db : self . db ,
178267 tls_config : self . tls_config ,
268+ backoff : self . backoff_config ,
179269 } )
180270 } else {
181271 Err ( Error :: InvalidConfig )
@@ -193,6 +283,7 @@ impl Default for ConfigBuilder {
193283 max_connections : DEFAULT_MAX_CONNECTIONS ,
194284 fetch_size : DEFAULT_FETCH_SIZE ,
195285 tls_config : ConnectionTLSConfig :: None ,
286+ backoff_config : Some ( BackoffConfig :: default ( ) ) ,
196287 }
197288 }
198289}
@@ -210,6 +301,7 @@ mod tests {
210301 . db ( "some_db" )
211302 . fetch_size ( 10 )
212303 . max_connections ( 5 )
304+ . with_backoff ( None )
213305 . build ( )
214306 . unwrap ( ) ;
215307 assert_eq ! ( config. uri, "127.0.0.1:7687" ) ;
@@ -219,6 +311,7 @@ mod tests {
219311 assert_eq ! ( config. fetch_size, 10 ) ;
220312 assert_eq ! ( config. max_connections, 5 ) ;
221313 assert_eq ! ( config. tls_config, ConnectionTLSConfig :: None ) ;
314+ assert_eq ! ( config. backoff, None ) ;
222315 }
223316
224317 #[ test]
@@ -236,6 +329,8 @@ mod tests {
236329 assert_eq ! ( config. fetch_size, 200 ) ;
237330 assert_eq ! ( config. max_connections, 16 ) ;
238331 assert_eq ! ( config. tls_config, ConnectionTLSConfig :: None ) ;
332+ assert ! ( config. backoff. is_some( ) ) ;
333+ assert_eq ! ( config. backoff. as_ref( ) . unwrap( ) , & BackoffConfig :: default ( ) ) ;
239334 }
240335
241336 #[ test]
@@ -245,6 +340,9 @@ mod tests {
245340 . user ( "some_user" )
246341 . password ( "some_password" )
247342 . skip_ssl_validation ( )
343+ . with_backoff ( Some (
344+ BackoffConfigBuilder :: new ( ) . with_multiplier ( 2.0 ) . build ( ) ,
345+ ) )
248346 . build ( )
249347 . unwrap ( ) ;
250348 assert_eq ! ( config. uri, "127.0.0.1:7687" ) ;
@@ -254,6 +352,8 @@ mod tests {
254352 assert_eq ! ( config. fetch_size, 200 ) ;
255353 assert_eq ! ( config. max_connections, 16 ) ;
256354 assert_eq ! ( config. tls_config, ConnectionTLSConfig :: NoSSLValidation ) ;
355+ assert ! ( config. backoff. is_some( ) ) ;
356+ assert_eq ! ( config. backoff. as_ref( ) . unwrap( ) . multiplier. unwrap( ) , 2.0 ) ;
257357 }
258358
259359 #[ test]
0 commit comments