1use std::{fmt, sync::Arc};
2
3use deadpool::{
4 managed::{self, Metrics, RecycleError, RecycleResult},
5 Runtime,
6};
7use deadpool_sync::SyncWrapper;
8
9pub struct Manager<M: r2d2::ManageConnection> {
15 r2d2_manager: Arc<M>,
16 runtime: Runtime,
17}
18
19impl<M: r2d2::ManageConnection> fmt::Debug for Manager<M>
21where
22 M: fmt::Debug,
23{
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 f.debug_struct("Manager")
26 .field("r2d2_manager", &self.r2d2_manager)
27 .field("runtime", &self.runtime)
28 .finish()
29 }
30}
31
32impl<M: r2d2::ManageConnection> Manager<M> {
33 #[must_use]
35 pub fn new(r2d2_manager: M, runtime: Runtime) -> Self {
36 Manager {
37 runtime,
38 r2d2_manager: Arc::new(r2d2_manager),
39 }
40 }
41}
42
43impl<M: r2d2::ManageConnection> managed::Manager for Manager<M>
44where
45 M::Error: Send,
46{
47 type Type = SyncWrapper<M::Connection>;
48 type Error = M::Error;
49
50 async fn create(&self) -> Result<Self::Type, Self::Error> {
51 let r2d2_manager = self.r2d2_manager.clone();
52 SyncWrapper::new(self.runtime, move || r2d2_manager.connect()).await
53 }
54
55 async fn recycle(&self, obj: &mut Self::Type, _: &Metrics) -> RecycleResult<Self::Error> {
56 if obj.is_mutex_poisoned() {
57 return Err(RecycleError::message(
58 "Mutex is poisoned. Connection is considered unusable.",
59 ));
60 }
61 let r2d2_manager = self.r2d2_manager.clone();
62 obj.interact::<_, RecycleResult<Self::Error>>(move |obj| {
63 if r2d2_manager.has_broken(obj) {
64 Err(RecycleError::message("Connection is broken"))
65 } else {
66 r2d2_manager.is_valid(obj).map_err(RecycleError::Backend)
67 }
68 })
69 .await
70 .map_err(|e| RecycleError::message(format!("Interaction failed: {}", e)))?
71 }
72}