hdbconnect_impl/conn/
connection_statistics.rs

1// docu is written at re-exports of frontend crates (hdbconnect/lib.rs, hdbconnect_async/lib.rs)
2#[derive(Debug, Clone)]
3pub struct ConnectionStatistics {
4    sequence_number: u32,
5    reset_base: u32,
6    compressed_requests_count: u32,
7    compressed_requests_compressed_size: u64,
8    compressed_requests_uncompressed_size: u64,
9    compressed_replies_compressed_size: u64,
10    compressed_replies_uncompressed_size: u64,
11    compressed_replies_count: u32,
12    shrinked_oversized_buffer_count: u32,
13    created_at: time::OffsetDateTime,
14    last_reset_at: time::OffsetDateTime,
15    wait_time: std::time::Duration,
16}
17impl Default for ConnectionStatistics {
18    fn default() -> Self {
19        let timestamp = time::OffsetDateTime::now_utc();
20        Self {
21            created_at: timestamp,
22            last_reset_at: timestamp,
23            sequence_number: 0,
24            reset_base: 0,
25            compressed_requests_count: 0,
26            compressed_requests_compressed_size: 0,
27            compressed_requests_uncompressed_size: 0,
28            compressed_replies_count: 0,
29            compressed_replies_compressed_size: 0,
30            compressed_replies_uncompressed_size: 0,
31            shrinked_oversized_buffer_count: 0,
32            wait_time: std::time::Duration::default(),
33        }
34    }
35}
36impl ConnectionStatistics {
37    pub(crate) fn new() -> Self {
38        Self::default()
39    }
40    pub(crate) fn reset(&mut self) {
41        *self = Self {
42            created_at: self.created_at,
43            last_reset_at: time::OffsetDateTime::now_utc(),
44            ..Default::default()
45        };
46    }
47
48    pub(crate) fn next_sequence_number(&mut self) -> u32 {
49        self.sequence_number += 1;
50        self.sequence_number
51    }
52
53    pub(crate) fn add_compressed_request(
54        &mut self,
55        compressed_size: usize,
56        uncompressed_parts_size: usize,
57    ) {
58        self.compressed_requests_count += 1;
59        self.compressed_requests_compressed_size += u64::try_from(compressed_size).unwrap(/*OK*/);
60        self.compressed_requests_uncompressed_size +=
61            u64::try_from(uncompressed_parts_size).unwrap(/*OK*/);
62    }
63
64    pub(crate) fn add_compressed_reply(
65        &mut self,
66        compressed_size: usize,
67        uncompressed_parts_size: usize,
68    ) {
69        self.compressed_replies_count += 1;
70        self.compressed_replies_compressed_size += u64::try_from(compressed_size).unwrap(/*OK*/);
71        self.compressed_replies_uncompressed_size +=
72            u64::try_from(uncompressed_parts_size).unwrap(/*OK*/);
73    }
74    pub(crate) fn add_wait_time(&mut self, wait_time: std::time::Duration) {
75        self.wait_time += wait_time;
76    }
77    pub(crate) fn add_buffer_shrinking(&mut self) {
78        self.shrinked_oversized_buffer_count += 1;
79    }
80
81    /// Returns the number of roundtrips to the database that were done through this connection
82    /// since the last reset.
83    #[must_use]
84    pub fn call_count(&self) -> u32 {
85        self.sequence_number - self.reset_base
86    }
87
88    /// Returns the total wait time, from start of serializing a request until receiving a reply,
89    /// for all roundtrips to the database that were done through this connection
90    /// since the last reset.
91    #[must_use]
92    pub fn accumulated_wait_time(&self) -> std::time::Duration {
93        self.wait_time
94    }
95
96    /// Returns the number of outgoing requests that were compressed.
97    #[must_use]
98    pub fn compressed_requests_count(&self) -> u32 {
99        self.compressed_requests_count
100    }
101
102    /// Returns the accumulated size of compressed requests (without message and segment header).
103    #[must_use]
104    pub fn compressed_requests_compressed_size(&self) -> u64 {
105        self.compressed_requests_compressed_size
106    }
107
108    /// Returns the accumulated uncompressed size (without message and segment header) of compressed requests.
109    #[must_use]
110    pub fn compressed_requests_uncompressed_size(&self) -> u64 {
111        self.compressed_requests_uncompressed_size
112    }
113
114    /// Returns the number of incoming replies that were compressed.
115    #[must_use]
116    pub fn compressed_replies_count(&self) -> u32 {
117        self.compressed_replies_count
118    }
119
120    /// Returns the accumulated size of compressed replies (without message and segment header).
121    #[must_use]
122    pub fn compressed_replies_compressed_size(&self) -> u64 {
123        self.compressed_replies_compressed_size
124    }
125
126    /// Returns the accumulated uncompressed size (without message and segment header) of compressed replies.
127    #[must_use]
128    pub fn compressed_replies_uncompressed_size(&self) -> u64 {
129        self.compressed_replies_uncompressed_size
130    }
131}
132
133impl std::fmt::Display for ConnectionStatistics {
134    #[allow(clippy::cast_precision_loss)]
135    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136        writeln!(f, "Connection statistics")?;
137        writeln!(f, "Created at:     {}", self.created_at)?;
138        writeln!(f, "Last reset at:  {}", self.last_reset_at)?;
139        writeln!(f, "Total number of requests: {}", self.sequence_number)?;
140        writeln!(f, "Total wait time:          {:?}", self.wait_time)?;
141        writeln!(
142            f,
143            "Buffer was shrinked:      {:?}",
144            self.shrinked_oversized_buffer_count
145        )?;
146        writeln!(f, "Compressed requests",)?;
147        writeln!(
148            f,
149            "  - count:                {}",
150            self.compressed_requests_count
151        )?;
152        if self.compressed_requests_uncompressed_size > 0 {
153            writeln!(
154                f,
155                "  - compression ratio:    {:.3}",
156                self.compressed_requests_uncompressed_size as f64
157                    / self.compressed_requests_compressed_size as f64
158            )?;
159        }
160        writeln!(f, "Compressed replies",)?;
161        writeln!(
162            f,
163            "  - count:                {}",
164            self.compressed_replies_count
165        )?;
166        if self.compressed_replies_uncompressed_size > 0 {
167            writeln!(
168                f,
169                "  - compression ratio:    {:.3}",
170                self.compressed_replies_uncompressed_size as f64
171                    / self.compressed_replies_compressed_size as f64
172            )?;
173        }
174        Ok(())
175    }
176}
177
178#[cfg(test)]
179mod test {
180    use super::ConnectionStatistics;
181
182    #[test]
183    fn test_statistics() {
184        let mut stat = ConnectionStatistics::default();
185        println!("{stat}");
186
187        stat.add_buffer_shrinking();
188        stat.add_compressed_reply(100, 800);
189        stat.add_compressed_request(200, 777);
190        println!("{stat}");
191
192        std::thread::sleep(std::time::Duration::from_millis(100));
193        stat.reset();
194        println!("{stat}");
195        assert_ne!(stat.created_at, stat.last_reset_at);
196    }
197}