Skip to main content

reinhardt_db/backends_pool/
events.rs

1//! Connection pool events
2
3use async_trait::async_trait;
4use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6
7/// Events that can occur in the connection pool
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub enum PoolEvent {
10	/// Connection acquired from pool
11	ConnectionAcquired {
12		/// The connection id.
13		connection_id: String,
14		/// The timestamp.
15		timestamp: DateTime<Utc>,
16	},
17
18	/// Connection returned to pool
19	ConnectionReturned {
20		/// The connection id.
21		connection_id: String,
22		/// The timestamp.
23		timestamp: DateTime<Utc>,
24	},
25
26	/// New connection created
27	ConnectionCreated {
28		/// The connection id.
29		connection_id: String,
30		/// The timestamp.
31		timestamp: DateTime<Utc>,
32	},
33
34	/// Connection closed
35	ConnectionClosed {
36		/// The connection id.
37		connection_id: String,
38		/// The reason.
39		reason: String,
40		/// The timestamp.
41		timestamp: DateTime<Utc>,
42	},
43
44	/// Connection test failed
45	ConnectionTestFailed {
46		/// The connection id.
47		connection_id: String,
48		/// The error.
49		error: String,
50		/// The timestamp.
51		timestamp: DateTime<Utc>,
52	},
53
54	/// Connection invalidated (hard invalidation)
55	ConnectionInvalidated {
56		/// The connection id.
57		connection_id: String,
58		/// The reason.
59		reason: String,
60		/// The timestamp.
61		timestamp: DateTime<Utc>,
62	},
63
64	/// Connection soft invalidated (can complete current operation)
65	ConnectionSoftInvalidated {
66		/// The connection id.
67		connection_id: String,
68		/// The timestamp.
69		timestamp: DateTime<Utc>,
70	},
71
72	/// Connection reset
73	ConnectionReset {
74		/// The connection id.
75		connection_id: String,
76		/// The timestamp.
77		timestamp: DateTime<Utc>,
78	},
79}
80
81impl PoolEvent {
82	/// Documentation for `connection_acquired`
83	///
84	pub fn connection_acquired(connection_id: String) -> Self {
85		Self::ConnectionAcquired {
86			connection_id,
87			timestamp: Utc::now(),
88		}
89	}
90	/// Documentation for `connection_returned`
91	///
92	pub fn connection_returned(connection_id: String) -> Self {
93		Self::ConnectionReturned {
94			connection_id,
95			timestamp: Utc::now(),
96		}
97	}
98	/// Documentation for `connection_created`
99	///
100	pub fn connection_created(connection_id: String) -> Self {
101		Self::ConnectionCreated {
102			connection_id,
103			timestamp: Utc::now(),
104		}
105	}
106	/// Documentation for `connection_closed`
107	///
108	pub fn connection_closed(connection_id: String, reason: String) -> Self {
109		Self::ConnectionClosed {
110			connection_id,
111			reason,
112			timestamp: Utc::now(),
113		}
114	}
115
116	/// Performs the connection test failed operation.
117	pub fn connection_test_failed(connection_id: String, error: String) -> Self {
118		Self::ConnectionTestFailed {
119			connection_id,
120			error,
121			timestamp: Utc::now(),
122		}
123	}
124	/// Documentation for `connection_invalidated`
125	///
126	pub fn connection_invalidated(connection_id: String, reason: String) -> Self {
127		Self::ConnectionInvalidated {
128			connection_id,
129			reason,
130			timestamp: Utc::now(),
131		}
132	}
133	/// Documentation for `connection_soft_invalidated`
134	///
135	pub fn connection_soft_invalidated(connection_id: String) -> Self {
136		Self::ConnectionSoftInvalidated {
137			connection_id,
138			timestamp: Utc::now(),
139		}
140	}
141	/// Documentation for `connection_reset`
142	///
143	pub fn connection_reset(connection_id: String) -> Self {
144		Self::ConnectionReset {
145			connection_id,
146			timestamp: Utc::now(),
147		}
148	}
149}
150
151/// Trait for listening to pool events
152#[async_trait]
153pub trait PoolEventListener: Send + Sync {
154	/// Handle a pool event
155	async fn on_event(&self, event: PoolEvent);
156}
157
158/// Simple event logger
159pub struct EventLogger;
160
161#[async_trait]
162impl PoolEventListener for EventLogger {
163	async fn on_event(&self, event: PoolEvent) {
164		match event {
165			PoolEvent::ConnectionAcquired { connection_id, .. } => {
166				println!("Connection acquired: {}", connection_id);
167			}
168			PoolEvent::ConnectionReturned { connection_id, .. } => {
169				println!("Connection returned: {}", connection_id);
170			}
171			PoolEvent::ConnectionCreated { connection_id, .. } => {
172				println!("Connection created: {}", connection_id);
173			}
174			PoolEvent::ConnectionClosed {
175				connection_id,
176				reason,
177				..
178			} => {
179				println!("Connection closed: {} (reason: {})", connection_id, reason);
180			}
181			PoolEvent::ConnectionTestFailed {
182				connection_id,
183				error,
184				..
185			} => {
186				println!(
187					"Connection test failed: {} (error: {})",
188					connection_id, error
189				);
190			}
191			PoolEvent::ConnectionInvalidated {
192				connection_id,
193				reason,
194				..
195			} => {
196				println!(
197					"Connection invalidated: {} (reason: {})",
198					connection_id, reason
199				);
200			}
201			PoolEvent::ConnectionSoftInvalidated { connection_id, .. } => {
202				println!("Connection soft invalidated: {}", connection_id);
203			}
204			PoolEvent::ConnectionReset { connection_id, .. } => {
205				println!("Connection reset: {}", connection_id);
206			}
207		}
208	}
209}
210
211#[cfg(test)]
212mod tests {
213	use super::*;
214
215	#[test]
216	fn test_pool_event_creation() {
217		let event = PoolEvent::connection_acquired("conn-1".to_string());
218		match event {
219			PoolEvent::ConnectionAcquired { connection_id, .. } => {
220				assert_eq!(connection_id, "conn-1");
221			}
222			_ => panic!("Wrong event type"),
223		}
224	}
225}