1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub enum HeartbeatChannel {
3 Platform,
4 Broker,
5}
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct HeartbeatRequestPlan {
9 pub pre_time_delay_ms: u32,
10}
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct HeartbeatSuccessFacts {
14 pub rtt_ms: u64,
15 pub server_time_secs: Option<u64>,
16 pub server_time_usec: Option<u64>,
17 pub local_recv_unix_micros: Option<u64>,
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub struct HeartbeatSuccessPlan {
22 pub next_pre_time_delay_ms: u32,
23 pub server_time_projection: Option<ServerTimeProjection>,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub enum HeartbeatFailureAction {
28 DisconnectAndStop,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub struct HeartbeatMachine {
33 channel: HeartbeatChannel,
34 last_rtt_ms: u32,
35}
36
37impl HeartbeatMachine {
38 #[must_use]
39 pub const fn new(channel: HeartbeatChannel) -> Self {
40 Self {
41 channel,
42 last_rtt_ms: 0,
43 }
44 }
45
46 #[must_use]
47 pub const fn request_plan(&self) -> HeartbeatRequestPlan {
48 HeartbeatRequestPlan {
49 pre_time_delay_ms: self.last_rtt_ms,
50 }
51 }
52
53 #[must_use]
54 pub fn record_success(&mut self, facts: HeartbeatSuccessFacts) -> HeartbeatSuccessPlan {
55 self.last_rtt_ms = u32::try_from(facts.rtt_ms).unwrap_or(u32::MAX);
56 HeartbeatSuccessPlan {
57 next_pre_time_delay_ms: self.last_rtt_ms,
58 server_time_projection: self.project_server_time(facts),
59 }
60 }
61
62 #[must_use]
63 pub const fn record_failure(&self) -> HeartbeatFailureAction {
64 HeartbeatFailureAction::DisconnectAndStop
65 }
66
67 fn project_server_time(&self, facts: HeartbeatSuccessFacts) -> Option<ServerTimeProjection> {
68 if self.channel != HeartbeatChannel::Platform {
69 return None;
70 }
71 project_server_time_sample_like_cpp(ServerTimeSampleFacts {
72 server_time_secs: facts.server_time_secs,
73 server_time_usec: facts.server_time_usec,
74 round_trip_micros: facts.rtt_ms.checked_mul(1_000)?,
75 local_receive_unix_micros: facts.local_recv_unix_micros,
76 })
77 }
78}
79use crate::server_time::{
80 ServerTimeProjection, ServerTimeSampleFacts, project_server_time_sample_like_cpp,
81};