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 background_tasks: self.background_tasks.clone(),
50 inner: Arc::clone(&self.inner),
51 }
52 .scan_collection(collection, cursor, limit)
53 }
54}
55
56impl Drop for RuntimeConnection {
57 fn drop(&mut self) {
58 let runtime = RedDBRuntime {
59 background_tasks: self.background_tasks.clone(),
60 inner: Arc::clone(&self.inner),
61 };
62 let reusable = match runtime.rollback_connection(self.id) {
65 Ok(_) => true,
66 Err(error) => {
67 tracing::error!(connection_id = self.id, %error, "connection rollback failed");
68 false
69 }
70 };
71 let mut pool = self
72 .inner
73 .pool
74 .lock()
75 .unwrap_or_else(|poisoned| poisoned.into_inner());
76 pool.active = pool.active.saturating_sub(1);
77 if self.uses_pool_slot {
78 pool.pooled_active = pool.pooled_active.saturating_sub(1);
79 }
80 if reusable && pool.idle.len() < self.inner.pool_config.max_idle {
81 pool.idle.push(self.id);
82 }
83 drop(pool);
84 self.inner.node_load_telemetry.record_disconnect();
86 }
87}