Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to retry connection creation, on by default #149

Merged
merged 3 commits into from
Mar 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions bb8/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ pub struct Builder<M: ManageConnection> {
pub(crate) idle_timeout: Option<Duration>,
/// 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<dyn ErrorSink<M::Error>>,
/// The time interval used to wake up and reap connections.
Expand All @@ -107,6 +109,7 @@ impl<M: ManageConnection> Default for Builder<M> {
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,
Expand Down Expand Up @@ -225,6 +228,20 @@ impl<M: ManageConnection> Builder<M> {
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.
///
Expand Down
4 changes: 3 additions & 1 deletion bb8/src/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down