diff --git a/bb8/src/api.rs b/bb8/src/api.rs index 794d58d..f0d1b82 100644 --- a/bb8/src/api.rs +++ b/bb8/src/api.rs @@ -89,6 +89,8 @@ pub struct Builder { pub(crate) idle_timeout: Option, /// The duration to wait to start a connection before giving up. pub(crate) connection_timeout: Duration, + /// Enable/disable automatic retries on connection creation. + pub(crate) retry_connection: bool, /// The error sink. pub(crate) error_sink: Box>, /// The time interval used to wake up and reap connections. @@ -107,6 +109,7 @@ impl Default for Builder { max_lifetime: Some(Duration::from_secs(30 * 60)), idle_timeout: Some(Duration::from_secs(10 * 60)), connection_timeout: Duration::from_secs(30), + retry_connection: true, error_sink: Box::new(NopErrorSink), reaper_rate: Duration::from_secs(30), connection_customizer: None, @@ -225,6 +228,20 @@ impl Builder { self } + /// Instructs the pool to automatically retry connection creation if it fails, until the `connection_timeout` has expired. + /// + /// Useful for transient connectivity errors like temporary DNS resolution failure + /// or intermittent network failures. Some applications however are smart enough to + /// know that the server is down and retries won't help (and could actually hurt recovery). + /// In that case, it's better to disable retries here and let the pool error out. + /// + /// Defaults to enabled. + #[must_use] + pub fn retry_connection(mut self, retry: bool) -> Self { + self.retry_connection = retry; + self + } + /// Set the sink for errors that are not associated with any particular operation /// on the pool. This can be used to log and monitor failures. /// diff --git a/bb8/src/inner.rs b/bb8/src/inner.rs index 71f6ab8..d206d9e 100644 --- a/bb8/src/inner.rs +++ b/bb8/src/inner.rs @@ -212,7 +212,9 @@ where return Ok(()); } Err(e) => { - if Instant::now() - start > self.inner.statics.connection_timeout { + if !self.inner.statics.retry_connection + || Instant::now() - start > self.inner.statics.connection_timeout + { let mut locked = shared.internals.lock(); locked.connect_failed(approval); return Err(e);