1use scheduled_thread_pool::ScheduledThreadPool;
2use std::fmt;
3use std::marker::PhantomData;
4use std::sync::Arc;
5use std::time::Duration;
6
7use crate::{
8 CustomizeConnection, Error, HandleError, HandleEvent, LoggingErrorHandler, ManageConnection,
9 NopConnectionCustomizer, NopEventHandler, Pool,
10};
11
12pub struct Builder<M>
14where
15 M: ManageConnection,
16{
17 max_size: u32,
18 min_idle: Option<u32>,
19 test_on_check_out: bool,
20 max_lifetime: Option<Duration>,
21 idle_timeout: Option<Duration>,
22 connection_timeout: Duration,
23 error_handler: Box<dyn HandleError<M::Error>>,
24 connection_customizer: Box<dyn CustomizeConnection<M::Connection, M::Error>>,
25 event_handler: Box<dyn HandleEvent>,
26 thread_pool: Option<Arc<ScheduledThreadPool>>,
27 reaper_rate: Duration,
28 _p: PhantomData<M>,
29}
30
31impl<M> fmt::Debug for Builder<M>
32where
33 M: ManageConnection,
34{
35 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
36 fmt.debug_struct("Builder")
37 .field("max_size", &self.max_size)
38 .field("min_idle", &self.min_idle)
39 .field("test_on_check_out", &self.test_on_check_out)
40 .field("max_lifetime", &self.max_lifetime)
41 .field("idle_timeout", &self.idle_timeout)
42 .field("connection_timeout", &self.connection_timeout)
43 .field("error_handler", &self.error_handler)
44 .field("event_handler", &self.event_handler)
45 .field("connection_customizer", &self.connection_customizer)
46 .finish()
47 }
48}
49
50impl<M> Default for Builder<M>
51where
52 M: ManageConnection,
53{
54 fn default() -> Builder<M> {
55 Builder {
56 max_size: 10,
57 min_idle: None,
58 test_on_check_out: true,
59 idle_timeout: Some(Duration::from_secs(10 * 60)),
60 max_lifetime: Some(Duration::from_secs(30 * 60)),
61 connection_timeout: Duration::from_secs(30),
62 error_handler: Box::new(LoggingErrorHandler),
63 event_handler: Box::new(NopEventHandler),
64 connection_customizer: Box::new(NopConnectionCustomizer),
65 thread_pool: None,
66 reaper_rate: Duration::from_secs(30),
67 _p: PhantomData,
68 }
69 }
70}
71
72impl<M> Builder<M>
73where
74 M: ManageConnection,
75{
76 pub fn new() -> Builder<M> {
80 Builder::default()
81 }
82
83 pub fn max_size(mut self, max_size: u32) -> Builder<M> {
91 assert!(max_size > 0, "max_size must be positive");
92 self.max_size = max_size;
93 self
94 }
95
96 pub fn min_idle(mut self, min_idle: Option<u32>) -> Builder<M> {
103 self.min_idle = min_idle;
104 self
105 }
106
107 pub fn thread_pool(mut self, thread_pool: Arc<ScheduledThreadPool>) -> Builder<M> {
112 self.thread_pool = Some(thread_pool);
113 self
114 }
115
116 pub fn test_on_check_out(mut self, test_on_check_out: bool) -> Builder<M> {
121 self.test_on_check_out = test_on_check_out;
122 self
123 }
124
125 pub fn max_lifetime(mut self, max_lifetime: Option<Duration>) -> Builder<M> {
139 assert_ne!(max_lifetime, Some(Duration::from_secs(0)), "max_lifetime must be positive");
140 self.max_lifetime = max_lifetime;
141 self
142 }
143
144 pub fn idle_timeout(mut self, idle_timeout: Option<Duration>) -> Builder<M> {
155 assert_ne!(idle_timeout, Some(Duration::from_secs(0)), "idle_timeout must be positive");
156 self.idle_timeout = idle_timeout;
157 self
158 }
159
160 pub fn connection_timeout(mut self, connection_timeout: Duration) -> Builder<M> {
171 assert!(
172 connection_timeout > Duration::from_secs(0),
173 "connection_timeout must be positive"
174 );
175 self.connection_timeout = connection_timeout;
176 self
177 }
178
179 pub fn error_handler(mut self, error_handler: Box<dyn HandleError<M::Error>>) -> Builder<M> {
183 self.error_handler = error_handler;
184 self
185 }
186
187 pub fn event_handler(mut self, event_handler: Box<dyn HandleEvent>) -> Builder<M> {
191 self.event_handler = event_handler;
192 self
193 }
194
195 pub fn connection_customizer(
199 mut self,
200 connection_customizer: Box<dyn CustomizeConnection<M::Connection, M::Error>>,
201 ) -> Builder<M> {
202 self.connection_customizer = connection_customizer;
203 self
204 }
205
206 #[allow(dead_code)]
208 pub(crate) fn reaper_rate(mut self, reaper_rate: Duration) -> Builder<M> {
209 self.reaper_rate = reaper_rate;
210 self
211 }
212
213 pub fn build(self, manager: M) -> Result<Pool<M>, Error> {
227 let pool = self.build_unchecked(manager);
228 pool.wait_for_initialization()?;
229 Ok(pool)
230 }
231
232 pub fn build_unchecked(self, manager: M) -> Pool<M> {
241 if let Some(min_idle) = self.min_idle {
242 assert!(
243 self.max_size >= min_idle,
244 "min_idle must be no larger than max_size"
245 );
246 }
247
248 let thread_pool = match self.thread_pool {
249 Some(thread_pool) => thread_pool,
250 None => Arc::new(ScheduledThreadPool::with_name("r2d2-worker-{}", 3)),
251 };
252
253 let config = Config {
254 max_size: self.max_size,
255 min_idle: self.min_idle,
256 test_on_check_out: self.test_on_check_out,
257 max_lifetime: self.max_lifetime,
258 idle_timeout: self.idle_timeout,
259 connection_timeout: self.connection_timeout,
260 error_handler: self.error_handler,
261 event_handler: self.event_handler,
262 connection_customizer: self.connection_customizer,
263 thread_pool,
264 };
265
266 Pool::new_inner(config, manager, self.reaper_rate)
267 }
268}
269
270pub struct Config<C, E> {
271 pub max_size: u32,
272 pub min_idle: Option<u32>,
273 pub test_on_check_out: bool,
274 pub max_lifetime: Option<Duration>,
275 pub idle_timeout: Option<Duration>,
276 pub connection_timeout: Duration,
277 pub error_handler: Box<dyn HandleError<E>>,
278 pub event_handler: Box<dyn HandleEvent>,
279 pub connection_customizer: Box<dyn CustomizeConnection<C, E>>,
280 pub thread_pool: Arc<ScheduledThreadPool>,
281}
282
283impl<C, E> fmt::Debug for Config<C, E> {
285 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
286 fmt.debug_struct("Config")
287 .field("max_size", &self.max_size)
288 .field("min_idle", &self.min_idle)
289 .field("test_on_check_out", &self.test_on_check_out)
290 .field("max_lifetime", &self.max_lifetime)
291 .field("idle_timeout", &self.idle_timeout)
292 .field("connection_timeout", &self.connection_timeout)
293 .field("error_handler", &self.error_handler)
294 .field("event_handler", &self.event_handler)
295 .field("connection_customizer", &self.connection_customizer)
296 .finish()
297 }
298}