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