mobc_forked/
config.rs

1use crate::metrics_utils::describe_metrics;
2use crate::{Manager, Pool};
3use std::marker::PhantomData;
4use std::time::Duration;
5
6const DEFAULT_MAX_IDLE_CONNS: u64 = 2;
7const DEFAULT_MAX_OPEN_CONNS: u64 = 10;
8const DEFAULT_BAD_CONN_RETRIES: u32 = 2;
9
10pub(crate) struct Config {
11    pub max_open: u64,
12    pub max_idle: u64,
13    pub max_lifetime: Option<Duration>,
14    pub max_idle_lifetime: Option<Duration>,
15    pub clean_rate: Duration,
16    pub max_bad_conn_retries: u32,
17    pub get_timeout: Option<Duration>,
18    pub health_check_interval: Option<Duration>,
19    pub health_check: bool,
20}
21
22impl Config {
23    pub fn split(self) -> (ShareConfig, InternalConfig) {
24        let share = ShareConfig {
25            clean_rate: self.clean_rate,
26            max_bad_conn_retries: self.max_bad_conn_retries,
27            get_timeout: self.get_timeout,
28            health_check: self.health_check,
29            health_check_interval: self.health_check_interval,
30        };
31
32        let internal = InternalConfig {
33            max_open: self.max_open,
34            max_idle: self.max_idle,
35            max_lifetime: self.max_lifetime,
36            max_idle_lifetime: self.max_idle_lifetime,
37        };
38
39        (share, internal)
40    }
41}
42
43pub(crate) struct ShareConfig {
44    pub clean_rate: Duration,
45    pub max_bad_conn_retries: u32,
46    pub get_timeout: Option<Duration>,
47    pub health_check: bool,
48    pub health_check_interval: Option<Duration>,
49}
50
51#[derive(Clone)]
52pub(crate) struct InternalConfig {
53    pub max_open: u64,
54    pub max_idle: u64,
55    pub max_lifetime: Option<Duration>,
56    pub max_idle_lifetime: Option<Duration>,
57}
58
59/// A builder for a connection pool.
60pub struct Builder<M> {
61    max_open: u64,
62    max_idle: Option<u64>,
63    max_lifetime: Option<Duration>,
64    max_idle_lifetime: Option<Duration>,
65    clean_rate: Duration,
66    max_bad_conn_retries: u32,
67    get_timeout: Option<Duration>,
68    health_check_interval: Option<Duration>,
69    health_check: bool,
70    _keep: PhantomData<M>,
71}
72
73impl<M> Default for Builder<M> {
74    fn default() -> Self {
75        Self {
76            max_open: DEFAULT_MAX_OPEN_CONNS,
77            max_idle: None,
78            max_lifetime: None,
79            max_idle_lifetime: None,
80            clean_rate: Duration::from_secs(1),
81            max_bad_conn_retries: DEFAULT_BAD_CONN_RETRIES,
82            get_timeout: Some(Duration::from_secs(30)),
83            _keep: PhantomData,
84            health_check: true,
85            health_check_interval: None,
86        }
87    }
88}
89
90impl<M: Manager> Builder<M> {
91    /// Constructs a new `Builder`.
92    ///
93    /// Parameters are initialized with their default values.
94    pub fn new() -> Self {
95        Default::default()
96    }
97
98    /// Sets the maximum number of connections managed by the pool.
99    ///
100    /// - 0 means unlimited.
101    /// - Defaults to 10.
102    pub fn max_open(mut self, max_open: u64) -> Self {
103        self.max_open = max_open;
104        self
105    }
106
107    /// Sets the maximum idle connection count maintained by the pool.
108    ///
109    /// The pool will maintain at most this many idle connections
110    /// at all times, while respecting the value of `max_open`.
111    ///
112    /// - Defaults to 2.
113    pub fn max_idle(mut self, max_idle: u64) -> Self {
114        self.max_idle = Some(max_idle);
115        self
116    }
117
118    /// If true, the health of a connection will be verified via a call to
119    /// `Manager::check` before it is checked out of the pool.
120    ///
121    /// - Defaults to true.
122    pub fn test_on_check_out(mut self, health_check: bool) -> Builder<M> {
123        self.health_check = health_check;
124        self
125    }
126
127    /// Sets the maximum lifetime of connections in the pool.
128    ///
129    /// Expired connections may be closed lazily before reuse.
130    ///
131    /// - `None` means reuse forever.
132    /// - Defaults to `None`.
133    ///
134    /// # Panics
135    ///
136    /// Panics if `max_lifetime` is the zero `Duration`.
137    pub fn max_lifetime(mut self, max_lifetime: Option<Duration>) -> Self {
138        assert_ne!(
139            max_lifetime,
140            Some(Duration::from_secs(0)),
141            "max_lifetime must be positive"
142        );
143        self.max_lifetime = max_lifetime;
144        self
145    }
146
147    /// Sets the maximum lifetime of connection to be idle in the pool,
148    /// resetting the timer when connection is used.
149    ///
150    /// Expired connections may be closed lazily before reuse.
151    ///
152    /// - `None` means reuse forever.
153    /// - Defaults to `None`.
154    ///
155    /// # Panics
156    ///
157    /// Panics if `max_idle_lifetime` is the zero `Duration`.
158    pub fn max_idle_lifetime(mut self, max_idle_lifetime: Option<Duration>) -> Self {
159        assert_ne!(
160            max_idle_lifetime,
161            Some(Duration::from_secs(0)),
162            "max_idle_lifetime must be positive"
163        );
164        self.max_idle_lifetime = max_idle_lifetime;
165        self
166    }
167
168    /// Sets the get timeout used by the pool.
169    ///
170    /// Calls to `Pool::get` will wait this long for a connection to become
171    /// available before returning an error.
172    ///
173    /// - `None` means never timeout.
174    /// - Defaults to 30 seconds.
175    ///
176    /// # Panics
177    ///
178    /// Panics if `connection_timeout` is the zero duration
179    pub fn get_timeout(mut self, get_timeout: Option<Duration>) -> Self {
180        assert_ne!(
181            get_timeout,
182            Some(Duration::from_secs(0)),
183            "get_timeout must be positive"
184        );
185
186        self.get_timeout = get_timeout;
187        self
188    }
189
190    /// Sets the interval how often a connection will be checked when returning
191    /// an existing connection from the pool. If set to `None`, a connection is
192    /// checked every time when returning from the pool. Must be used together
193    /// with [`test_on_check_out`] set to `true`, otherwise does nothing.
194    ///
195    /// - `None` means a connection is checked every time when returning from the
196    ///   pool.
197    /// - Defaults to `None`.
198    ///
199    /// # Panics
200    ///
201    /// Panics if `connection_timeout` is the zero duration
202    ///
203    /// [`test_on_check_out`]: #method.test_on_check_out
204    pub fn health_check_interval(mut self, health_check_interval: Option<Duration>) -> Self {
205        assert_ne!(
206            health_check_interval,
207            Some(Duration::from_secs(0)),
208            "health_check_interval must be positive"
209        );
210
211        self.health_check_interval = health_check_interval;
212        self
213    }
214    // used by tests
215    #[doc(hidden)]
216    #[allow(dead_code)]
217    pub fn clean_rate(mut self, clean_rate: Duration) -> Builder<M> {
218        assert!(
219            clean_rate > Duration::from_secs(0),
220            "connection_timeout must be positive"
221        );
222
223        if clean_rate > Duration::from_secs(1) {
224            self.clean_rate = clean_rate;
225        }
226
227        self
228    }
229
230    /// Consumes the builder, returning a new, initialized pool.
231    ///
232    /// # Panics
233    ///
234    /// Panics if `max_idle` is greater than `max_size`.
235    pub fn build(self, manager: M) -> Pool<M> {
236        use std::cmp;
237
238        describe_metrics();
239        let max_idle = self
240            .max_idle
241            .unwrap_or_else(|| cmp::min(self.max_open, DEFAULT_MAX_IDLE_CONNS));
242
243        assert!(
244            self.max_open >= max_idle,
245            "max_idle must be no larger than max_open"
246        );
247
248        let config = Config {
249            max_open: self.max_open,
250            max_idle,
251            max_lifetime: self.max_lifetime,
252            max_idle_lifetime: self.max_idle_lifetime,
253            get_timeout: self.get_timeout,
254            clean_rate: self.clean_rate,
255            max_bad_conn_retries: self.max_bad_conn_retries,
256            health_check: self.health_check,
257            health_check_interval: self.health_check_interval,
258        };
259
260        Pool::new_inner(manager, config)
261    }
262}