1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
use std::{fmt, time::Duration};
use super::BuildError;
/// [`Pool`] configuration.
///
/// [`Pool`]: super::Pool
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct PoolConfig {
/// Maximum size of the [`Pool`].
///
/// Default: `cpu_count * 4`
///
/// [`Pool`]: super::Pool
pub max_size: usize,
/// Timeouts of the [`Pool`].
///
/// Default: No timeouts
///
/// [`Pool`]: super::Pool
#[cfg_attr(feature = "serde", serde(default))]
pub timeouts: Timeouts,
/// Queue mode of the [`Pool`].
///
/// Determines the order of objects being queued and dequeued.
///
/// Default: `Fifo`
///
/// [`Pool`]: super::Pool
#[cfg_attr(feature = "serde", serde(default))]
pub queue_mode: QueueMode,
}
impl PoolConfig {
/// Creates a new [`PoolConfig`] without any timeouts and with the provided
/// `max_size`.
#[must_use]
pub fn new(max_size: usize) -> Self {
Self {
max_size,
timeouts: Timeouts::default(),
queue_mode: QueueMode::default(),
}
}
}
impl Default for PoolConfig {
/// Creates a new [`PoolConfig`] with the `max_size` being set to
/// `cpu_count * 4` ignoring any logical CPUs (Hyper-Threading).
fn default() -> Self {
Self::new(num_cpus::get_physical() * 4)
}
}
/// Timeouts when getting [`Object`]s from a [`Pool`].
///
/// [`Object`]: super::Object
/// [`Pool`]: super::Pool
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Timeouts {
/// Timeout when waiting for a slot to become available.
pub wait: Option<Duration>,
/// Timeout when creating a new object.
pub create: Option<Duration>,
/// Timeout when recycling an object.
pub recycle: Option<Duration>,
}
impl Timeouts {
/// Create an empty [`Timeouts`] config (no timeouts set).
#[must_use]
pub const fn new() -> Self {
Self {
create: None,
wait: None,
recycle: None,
}
}
/// Creates a new [`Timeouts`] config with only the `wait` timeout being
/// set.
#[must_use]
pub const fn wait_millis(wait: u64) -> Self {
Self {
create: None,
wait: Some(Duration::from_millis(wait)),
recycle: None,
}
}
}
// Implemented manually to provide a custom documentation.
impl Default for Timeouts {
/// Creates an empty [`Timeouts`] config (no timeouts set).
fn default() -> Self {
Self::new()
}
}
/// Mode for dequeuing [`Object`]s from a [`Pool`].
///
/// [`Object`]: super::Object
/// [`Pool`]: super::Pool
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum QueueMode {
/// Dequeue the object that was least recently added (first in first out).
Fifo,
/// Dequeue the object that was most recently added (last in first out).
Lifo,
}
impl Default for QueueMode {
fn default() -> Self {
Self::Fifo
}
}
/// This error is used when building pools via the config `create_pool`
/// methods.
#[derive(Debug)]
pub enum CreatePoolError<C> {
/// This variant is used for configuration errors
Config(C),
/// This variant is used for errors while building the pool
Build(BuildError),
}
impl<C> fmt::Display for CreatePoolError<C>
where
C: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Config(e) => write!(f, "Config: {}", e),
Self::Build(e) => write!(f, "Build: {}", e),
}
}
}
impl<C> std::error::Error for CreatePoolError<C> where C: std::error::Error {}