1#![doc = include_str!("../readme.md")]
6#![forbid(unsafe_code)]
7
8mod core;
9mod multiplex;
10mod retirement;
11mod singleplex;
12
13pub use multiplex::{
14 Admission, MultiplexAbandonedUse, MultiplexBuildPermit, MultiplexPool, MultiplexReservation,
15 MultiplexResource, MultiplexUse, UseId,
16};
17pub use retirement::Retirement;
18pub use singleplex::{SingleplexBuildPermit, SingleplexLease, SingleplexPool, SingleplexResource};
19
20use base_scheduler::Cancellation;
21use std::{fmt, future::Future};
22
23#[derive(Clone, Debug)]
25pub struct Options {
26 pub max_resources: usize,
27 pub max_constructing: usize,
28 pub max_waiters: usize,
29}
30impl Default for Options {
31 fn default() -> Self {
32 Self {
33 max_resources: 32,
34 max_constructing: 1,
35 max_waiters: 1024,
36 }
37 }
38}
39impl Options {
40 pub fn validate(&self) -> Result<(), Error> {
41 if self.max_resources == 0 || self.max_constructing == 0 {
42 Err(Error::InvalidOptions)
43 } else {
44 Ok(())
45 }
46 }
47}
48
49#[derive(Clone, Copy, Debug, Eq, PartialEq)]
50pub enum Error {
51 Closed,
52 Cancelled,
53 WaitersFull,
54 AdmissionChanged,
55 InvalidOptions,
56}
57impl fmt::Display for Error {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 f.write_str(match self {
60 Self::Closed => "pool admission is closed",
61 Self::Cancelled => "pool operation cancelled",
62 Self::WaitersFull => "pool waiter limit reached",
63 Self::AdmissionChanged => "resource admission changed before use activation",
64 Self::InvalidOptions => "resource and construction limits must be positive",
65 })
66 }
67}
68impl std::error::Error for Error {}
69impl From<base_scheduler::Cancelled> for Error {
70 fn from(_: base_scheduler::Cancelled) -> Self {
71 Self::Cancelled
72 }
73}
74
75#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
77pub struct ResourceId(pub(crate) u64);
78
79#[derive(Debug)]
82pub enum Acquisition<P, B> {
83 Existing(P),
84 Build(B),
85}
86
87#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
89pub struct Stats {
90 pub building: usize,
91 pub live: usize,
92 pub retiring: usize,
93 pub draining: usize,
94 pub uses: usize,
95 pub available: usize,
96 pub waiters: usize,
97 pub closed: bool,
98}
99impl Stats {
100 pub fn total(&self) -> usize {
101 self.building + self.live + self.retiring
102 }
103}
104
105pub trait Pool: Send + Sync {
108 type Permit: Send;
109 type BuildPermit: Send;
110 fn acquire_or_reserve(
111 &self,
112 cancellation: &Cancellation,
113 ) -> impl Future<Output = Result<Acquisition<Self::Permit, Self::BuildPermit>, Error>> + Send;
114 fn begin_close(&self);
115 fn stats(&self) -> Stats;
116}