reddb_server/runtime/
health_connection.rs1use super::*;
2
3impl HealthProvider for RedDBRuntime {
4 fn health(&self) -> HealthReport {
5 let pool = self
6 .inner
7 .pool
8 .lock()
9 .unwrap_or_else(|poisoned| poisoned.into_inner());
10 let mut report = self.inner.db.health();
11 let (readiness_for_query, readiness_for_write, readiness_for_repair) =
12 self.inner.db.readiness_flags_from_health(&report);
13 report = report.with_diagnostic(
14 "runtime.mode",
15 if self.inner.layout.is_persistent() {
16 "persistent"
17 } else {
18 "in-memory"
19 },
20 );
21 report = report.with_diagnostic("runtime.active_connections", pool.active.to_string());
22 report = report.with_diagnostic("runtime.idle_connections", pool.idle.len().to_string());
23 report = report.with_diagnostic("readiness_for_query", readiness_for_query.to_string());
24 report = report.with_diagnostic("readiness_for_write", readiness_for_write.to_string());
25 report = report.with_diagnostic("readiness_for_repair", readiness_for_repair.to_string());
26 report.with_diagnostic(
27 "runtime.max_connections",
28 self.inner.pool_config.max_connections.to_string(),
29 )
30 }
31}
32
33impl RuntimeConnection {
34 pub fn id(&self) -> u64 {
35 self.id
36 }
37
38 pub fn db(&self) -> Arc<RedDB> {
39 Arc::clone(&self.inner.db)
40 }
41
42 pub fn scan_collection(
43 &self,
44 collection: &str,
45 cursor: Option<ScanCursor>,
46 limit: usize,
47 ) -> RedDBResult<ScanPage> {
48 RedDBRuntime {
49 inner: Arc::clone(&self.inner),
50 }
51 .scan_collection(collection, cursor, limit)
52 }
53}
54
55impl Drop for RuntimeConnection {
56 fn drop(&mut self) {
57 let runtime = RedDBRuntime {
58 inner: Arc::clone(&self.inner),
59 };
60 let reusable = match runtime.rollback_connection(self.id) {
63 Ok(_) => true,
64 Err(error) => {
65 tracing::error!(connection_id = self.id, %error, "connection rollback failed");
66 false
67 }
68 };
69 let mut pool = self
70 .inner
71 .pool
72 .lock()
73 .unwrap_or_else(|poisoned| poisoned.into_inner());
74 pool.active = pool.active.saturating_sub(1);
75 if self.uses_pool_slot {
76 pool.pooled_active = pool.pooled_active.saturating_sub(1);
77 }
78 if reusable && pool.idle.len() < self.inner.pool_config.max_idle {
79 pool.idle.push(self.id);
80 }
81 drop(pool);
82 self.inner.node_load_telemetry.record_disconnect();
84 }
85}