Skip to content

Commit

Permalink
Add LIFO option for getting pool resources (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
zainkabani committed May 26, 2023
1 parent 0368c60 commit c6c8c0d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
30 changes: 30 additions & 0 deletions bb8/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,31 @@ pub struct Builder<M: ManageConnection> {
pub(crate) error_sink: Box<dyn ErrorSink<M::Error>>,
/// 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<Box<dyn CustomizeConnection<M::Connection, M::Error>>>,
_p: PhantomData<M>,
}

#[derive(Debug)]
pub enum QueueStrategy {
/// First in first out
/// This strategy behaves like a queue
/// It will evenly spread load on all existing connections, resetting their idle timeouts, maintaining the pool size
Fifo,
/// Last in first out
/// This behaves like a stack
/// It will use the most recently used connection and help to keep the total pool size small by evicting idle connections
Lifo,
}

impl Default for QueueStrategy {
fn default() -> Self {
QueueStrategy::Fifo
}
}

impl<M: ManageConnection> Default for Builder<M> {
fn default() -> Self {
Builder {
Expand All @@ -112,6 +132,7 @@ impl<M: ManageConnection> Default for Builder<M> {
retry_connection: true,
error_sink: Box::new(NopErrorSink),
reaper_rate: Duration::from_secs(30),
queue_strategy: QueueStrategy::default(),
connection_customizer: None,
_p: PhantomData,
}
Expand Down Expand Up @@ -260,6 +281,15 @@ impl<M: ManageConnection> Builder<M> {
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(
Expand Down
11 changes: 8 additions & 3 deletions bb8/src/internals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -42,6 +42,7 @@ where
conns: VecDeque<IdleConn<M::Connection>>,
num_conns: u32,
pending_conns: u32,
queue_strategy: QueueStrategy,
}

impl<M> PoolInternals<M>
Expand Down Expand Up @@ -80,8 +81,11 @@ where
}

// Queue it in the idle queue
self.conns
.push_back(IdleConn::from(guard.conn.take().unwrap()));
let conn = IdleConn::from(guard.conn.take().unwrap());
match self.queue_strategy {
QueueStrategy::Fifo => self.conns.push_back(conn),
QueueStrategy::Lifo => self.conns.push_front(conn),
}
}

pub(crate) fn connect_failed(&mut self, _: Approval) {
Expand Down Expand Up @@ -163,6 +167,7 @@ where
conns: VecDeque::new(),
num_conns: 0,
pending_conns: 0,
queue_strategy: QueueStrategy::Lifo,
}
}
}
Expand Down

0 comments on commit c6c8c0d

Please sign in to comment.