Skip to main content

futu_core/
heartbeat.rs

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};