use std::time::Duration;
use futures::{
future::{self, Future},
try_ready, Async, Poll,
};
use crate::config::Builder;
use crate::instrumentation::NoInstrumentation;
use crate::pool_internal::CheckoutManaged;
mod activation_order;
mod backoff_strategy;
mod commands;
mod error;
mod multi_node_pool;
mod pool_internal;
mod pooled_connection;
mod single_node_pool;
pub(crate) mod executor_flavour;
pub(crate) mod connection_factory;
pub(crate) mod helpers;
pub mod config;
pub mod instrumentation;
pub use crate::error::{CheckoutError, CheckoutErrorKind};
pub use commands::Commands;
use pooled_connection::ConnectionFlavour;
pub use pooled_connection::RedisConnection;
mod redis_rs;
pub trait Poolable: Send + Sized + 'static {}
pub struct Checkout(CheckoutManaged<ConnectionFlavour>);
impl Future for Checkout {
type Item = RedisConnection;
type Error = CheckoutError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let managed = try_ready!(self.0.poll());
Ok(Async::Ready(RedisConnection {
managed,
connection_state_ok: true,
}))
}
}
#[derive(Clone)]
enum RedisPoolFlavour {
NoPool,
SingleNode(single_node_pool::SingleNodePool),
MultiNode(multi_node_pool::MultiNodePool),
}
#[derive(Clone)]
pub struct RedisPool(RedisPoolFlavour);
impl RedisPool {
pub fn builder() -> Builder<NoInstrumentation> {
Builder::default()
}
pub fn no_pool() -> Self {
RedisPool(RedisPoolFlavour::NoPool)
}
pub fn check_out(&self) -> Checkout {
match self.0 {
RedisPoolFlavour::SingleNode(ref pool) => pool.check_out(),
RedisPoolFlavour::MultiNode(ref pool) => pool.check_out(),
RedisPoolFlavour::NoPool => Checkout(CheckoutManaged::new(future::err(
CheckoutError::new(CheckoutErrorKind::NoPool),
))),
}
}
pub fn check_out_explicit_timeout(&self, timeout: Option<Duration>) -> Checkout {
match self.0 {
RedisPoolFlavour::SingleNode(ref pool) => pool.check_out_explicit_timeout(timeout),
RedisPoolFlavour::MultiNode(ref pool) => pool.check_out_explicit_timeout(timeout),
RedisPoolFlavour::NoPool => Checkout(CheckoutManaged::new(future::err(
CheckoutError::new(CheckoutErrorKind::NoPool),
))),
}
}
pub fn stats(&self) -> Vec<self::stats::PoolStats> {
match self.0 {
RedisPoolFlavour::SingleNode(ref pool) => vec![pool.stats()],
RedisPoolFlavour::MultiNode(ref pool) => pool.stats(),
RedisPoolFlavour::NoPool => Vec::new(),
}
}
pub fn trigger_stats(&self) {
match self.0 {
RedisPoolFlavour::SingleNode(ref pool) => pool.trigger_stats(),
RedisPoolFlavour::MultiNode(ref pool) => pool.trigger_stats(),
RedisPoolFlavour::NoPool => {}
}
}
}
pub mod stats {
#[derive(Debug, Clone)]
pub struct PoolStats {
pub pool_size: MinMax,
pub in_flight: MinMax,
pub reservations: MinMax,
pub idle: MinMax,
pub node_count: usize,
}
impl Default for PoolStats {
fn default() -> Self {
Self {
pool_size: MinMax::default(),
in_flight: MinMax::default(),
reservations: MinMax::default(),
idle: MinMax::default(),
node_count: 0,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct MinMax<T = usize>(pub T, pub T);
impl<T> MinMax<T>
where
T: Copy,
{
pub fn min(&self) -> T {
self.0
}
pub fn max(&self) -> T {
self.1
}
}
impl<T> Default for MinMax<T>
where
T: Default,
{
fn default() -> Self {
Self(T::default(), T::default())
}
}
}