Skip to content

Commit 8c6f189

Browse files
committed
An attempt at refactoring peer timer
1 parent 6a6f7e3 commit 8c6f189

2 files changed

Lines changed: 39 additions & 21 deletions

File tree

crates/hotfix/src/session.rs

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ pub struct SessionRef<M> {
4444
sender: mpsc::Sender<SessionEvent<M>>,
4545
}
4646

47-
const TEST_REQUEST_THRESHOLD: f64 = 1.2;
4847
type TestRequestId = String;
4948

5049
impl<M: FixMessage> SessionRef<M> {
@@ -119,8 +118,6 @@ struct Session<M, S> {
119118
application: ApplicationRef<M>,
120119
store: S,
121120
awaiting_test_response: Option<TestRequestId>,
122-
123-
peer_timer: Pin<Box<Sleep>>,
124121
schedule_check_timer: Pin<Box<Sleep>>,
125122
}
126123

@@ -131,9 +128,6 @@ impl<M: FixMessage, S: MessageStore> Session<M, S> {
131128
application: ApplicationRef<M>,
132129
store: S,
133130
) -> Session<M, S> {
134-
let peer_timer = sleep(Duration::from_secs(
135-
(config.heartbeat_interval as f64 * TEST_REQUEST_THRESHOLD).round() as u64,
136-
));
137131
let schedule_check_timer = sleep(Duration::from_secs(SCHEDULE_CHECK_INTERVAL));
138132

139133
let dictionary = Self::get_data_dictionary(&config);
@@ -149,7 +143,6 @@ impl<M: FixMessage, S: MessageStore> Session<M, S> {
149143
application,
150144
store,
151145
awaiting_test_response: None,
152-
peer_timer: Box::pin(peer_timer),
153146
schedule_check_timer: Box::pin(schedule_check_timer),
154147
}
155148
}
@@ -544,11 +537,8 @@ impl<M: FixMessage, S: MessageStore> Session<M, S> {
544537
}
545538

546539
fn reset_peer_timer(&mut self, awaiting_req_id: Option<TestRequestId>) {
547-
let seconds =
548-
(self.config.heartbeat_interval as f64 * TEST_REQUEST_THRESHOLD).round() as u64;
549-
let deadline = Instant::now() + Duration::from_secs(seconds);
550-
self.peer_timer.as_mut().reset(deadline);
551540
self.awaiting_test_response = awaiting_req_id;
541+
self.state.reset_peer_timer(self.config.heartbeat_interval);
552542
}
553543

554544
async fn send_message(&mut self, message: impl FixMessage) {
@@ -616,7 +606,6 @@ impl<M: FixMessage, S: MessageStore> Session<M, S> {
616606
async fn logout_and_terminate(&mut self, reason: &str) {
617607
self.logout(reason).await;
618608
self.state.disconnect().await;
619-
self.disable_peer_timer().await;
620609
}
621610

622611
async fn initiate_graceful_logout(&mut self, reason: &str) {
@@ -711,13 +700,6 @@ impl<M: FixMessage, S: MessageStore> Session<M, S> {
711700
let deadline = Instant::now() + Duration::from_secs(SCHEDULE_CHECK_INTERVAL);
712701
self.schedule_check_timer.as_mut().reset(deadline);
713702
}
714-
715-
async fn disable_peer_timer(&mut self) {
716-
// push the timer out by about a month - there is no way to disable it entirely afaik
717-
self.peer_timer
718-
.as_mut()
719-
.reset(Instant::now() + Duration::from_secs(2592000));
720-
}
721703
}
722704

723705
async fn run_session<M, S>(mut session: Session<M, S>)
@@ -727,6 +709,8 @@ where
727709
{
728710
loop {
729711
let next_message = session.mailbox.recv();
712+
let heartbeat_timer = session.state.heartbeat_timer();
713+
let peer_timer = session.state.peer_timer();
730714

731715
select! {
732716
next = next_message => {
@@ -738,15 +722,21 @@ where
738722
}
739723
}
740724
() = async {
741-
if let Some(timer) = session.state.heartbeat_timer() {
725+
if let Some(timer) = heartbeat_timer {
742726
timer.as_mut().await
743727
} else {
744728
std::future::pending().await
745729
}
746730
} => {
747731
session.handle_heartbeat_timeout().await;
748732
}
749-
() = &mut session.peer_timer.as_mut() => {
733+
() = async {
734+
if let Some(timer) = peer_timer {
735+
timer.as_mut().await
736+
} else {
737+
std::future::pending().await
738+
}
739+
} => {
750740
session.handle_peer_timeout().await;
751741
}
752742
() = &mut session.schedule_check_timer.as_mut() => {

crates/hotfix/src/session/state.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use tokio::sync::oneshot;
99
use tokio::time::{Instant, Sleep, sleep};
1010
use tracing::{debug, error};
1111

12+
const TEST_REQUEST_THRESHOLD: f64 = 1.2;
13+
1214
pub enum SessionState {
1315
/// We have established a connection, sent a logon message and await a response.
1416
AwaitingLogon { writer: WriterRef, logon_sent: bool },
@@ -34,9 +36,14 @@ impl SessionState {
3436

3537
pub fn new_active(writer: WriterRef, heartbeat_interval: u64) -> Self {
3638
let heartbeat_timer = Box::pin(sleep(Duration::from_secs(heartbeat_interval)));
39+
40+
let peer_interval = calculate_peer_interval(heartbeat_interval);
41+
let peer_timer = Box::pin(sleep(Duration::from_secs(peer_interval)));
42+
3743
Self::Active(ActiveState {
3844
writer,
3945
heartbeat_timer,
46+
peer_timer,
4047
})
4148
}
4249

@@ -168,11 +175,32 @@ impl SessionState {
168175
heartbeat_timer.as_mut().reset(deadline);
169176
}
170177
}
178+
179+
pub fn peer_timer(&mut self) -> Option<&mut Pin<Box<Sleep>>> {
180+
match self {
181+
Self::Active(ActiveState { peer_timer, .. }) => Some(peer_timer),
182+
_ => None,
183+
}
184+
}
185+
186+
pub fn reset_peer_timer(&mut self, heartbeat_interval: u64) {
187+
if let Self::Active(ActiveState { peer_timer, .. }) = self {
188+
let interval = calculate_peer_interval(heartbeat_interval);
189+
let deadline = Instant::now() + Duration::from_secs(interval);
190+
peer_timer.as_mut().reset(deadline);
191+
}
192+
}
193+
}
194+
195+
#[inline]
196+
fn calculate_peer_interval(heartbeat_interval: u64) -> u64 {
197+
(heartbeat_interval as f64 * TEST_REQUEST_THRESHOLD).round() as u64
171198
}
172199

173200
pub struct ActiveState {
174201
writer: WriterRef,
175202
heartbeat_timer: Pin<Box<Sleep>>,
203+
peer_timer: Pin<Box<Sleep>>,
176204
}
177205

178206
/// Session state we're in while processing messages we requested to be resent.

0 commit comments

Comments
 (0)