diff --git a/bb8/src/api.rs b/bb8/src/api.rs index f0d1b82..e1a72fe 100644 --- a/bb8/src/api.rs +++ b/bb8/src/api.rs @@ -74,6 +74,14 @@ impl Pool { } } +#[derive(Debug)] +pub enum QueueStrategy { + /// Last in first out + LIFO, + /// First in first out + FIFO, +} + /// A builder for a connection pool. #[derive(Debug)] pub struct Builder { @@ -95,6 +103,8 @@ pub struct Builder { pub(crate) error_sink: Box>, /// The time interval used to wake up and reap connections. pub(crate) reaper_rate: Duration, + /// Queue strategy (FIFO or LIFO) + pub(crate) queue_strategy: QueueStrategy, /// User-supplied trait object responsible for initializing connections pub(crate) connection_customizer: Option>>, _p: PhantomData, @@ -112,6 +122,7 @@ impl Default for Builder { retry_connection: true, error_sink: Box::new(NopErrorSink), reaper_rate: Duration::from_secs(30), + queue_strategy: QueueStrategy::FIFO, connection_customizer: None, _p: PhantomData, } @@ -260,6 +271,15 @@ impl Builder { self } + /// Sets the queue strategy to be used by the pool + /// + /// Defaults to `FIFO`. + #[must_use] + pub fn queue_strategy(mut self, queue_strategy: QueueStrategy) -> Self { + self.queue_strategy = queue_strategy; + self + } + /// Set the connection customizer to customize newly checked out connections #[must_use] pub fn connection_customizer( diff --git a/bb8/src/internals.rs b/bb8/src/internals.rs index cffd928..1ec3e42 100644 --- a/bb8/src/internals.rs +++ b/bb8/src/internals.rs @@ -2,7 +2,7 @@ use std::cmp::min; use std::sync::Arc; use std::time::Instant; -use crate::lock::Mutex; +use crate::{api::QueueStrategy, lock::Mutex}; use futures_channel::oneshot; use crate::api::{Builder, ManageConnection}; @@ -42,6 +42,7 @@ where conns: VecDeque>, num_conns: u32, pending_conns: u32, + queue_strategy: QueueStrategy, } impl PoolInternals @@ -80,8 +81,14 @@ where } // Queue it in the idle queue - self.conns - .push_back(IdleConn::from(guard.conn.take().unwrap())); + match self.queue_strategy { + QueueStrategy::FIFO => self + .conns + .push_back(IdleConn::from(guard.conn.take().unwrap())), + QueueStrategy::LIFO => self + .conns + .push_front(IdleConn::from(guard.conn.take().unwrap())), + } } pub(crate) fn connect_failed(&mut self, _: Approval) { @@ -163,6 +170,7 @@ where conns: VecDeque::new(), num_conns: 0, pending_conns: 0, + queue_strategy: QueueStrategy::LIFO, } } }