Skip to content

Commit 9a770cc

Browse files
committed
Add API to get information on the session
1 parent e03323d commit 9a770cc

4 files changed

Lines changed: 63 additions & 0 deletions

File tree

crates/hotfix/src/session.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod event;
2+
mod info;
23
mod state;
34

45
use anyhow::{Result, anyhow};
@@ -31,6 +32,7 @@ use crate::message::sequence_reset::SequenceReset;
3132
use crate::message::test_request::TestRequest;
3233
use crate::message_utils::is_admin;
3334
use crate::session::event::AwaitingActiveSessionResponse;
35+
use crate::session::info::SessionInfo;
3436
use crate::session::state::{AwaitingResendState, TestRequestId};
3537
use crate::session_schedule::SessionSchedule;
3638
use event::SessionEvent;
@@ -104,6 +106,15 @@ impl<M: FixMessage> SessionRef<M> {
104106
receiver.await.expect("to receive a response");
105107
debug!("resuming connection as session is active");
106108
}
109+
110+
pub async fn get_session_info(&self) -> SessionInfo {
111+
let (sender, receiver) = oneshot::channel::<SessionInfo>();
112+
self.sender
113+
.send(SessionEvent::SessionInfoRequested(sender))
114+
.await
115+
.unwrap();
116+
receiver.await.expect("to receive a response")
117+
}
107118
}
108119

109120
struct Session<M, S> {
@@ -639,6 +650,11 @@ impl<M: FixMessage, S: MessageStore> Session<M, S> {
639650
SessionEvent::AwaitingActiveSession(responder) => {
640651
self.state.register_session_awaiter(responder);
641652
}
653+
SessionEvent::SessionInfoRequested(responder) => {
654+
if responder.send(self.get_session_info()).is_err() {
655+
error!("failed to respond to session info request");
656+
}
657+
}
642658
}
643659
}
644660

@@ -696,6 +712,14 @@ impl<M: FixMessage, S: MessageStore> Session<M, S> {
696712
let deadline = Instant::now() + Duration::from_secs(SCHEDULE_CHECK_INTERVAL);
697713
self.schedule_check_timer.as_mut().reset(deadline);
698714
}
715+
716+
fn get_session_info(&self) -> SessionInfo {
717+
SessionInfo {
718+
next_sender_seq_number: self.store.next_sender_seq_number(),
719+
next_target_seq_number: self.store.next_target_seq_number(),
720+
status: self.state.as_status(),
721+
}
722+
}
699723
}
700724

701725
async fn run_session<M, S>(mut session: Session<M, S>)

crates/hotfix/src/session/event.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use tokio::sync::oneshot;
22

33
use crate::message::parser::RawFixMessage;
4+
use crate::session::info::SessionInfo;
45
use crate::transport::writer::WriterRef;
56

67
#[derive(Debug)]
@@ -17,6 +18,8 @@ pub enum SessionEvent<M> {
1718
ShouldReconnect(oneshot::Sender<bool>),
1819
/// Ask the session to notify us when the session is active.
1920
AwaitingActiveSession(oneshot::Sender<AwaitingActiveSessionResponse>),
21+
/// Ask the session for a report on its state
22+
SessionInfoRequested(oneshot::Sender<SessionInfo>),
2023
}
2124

2225
/// The response sent by the session to AwaitingActiveSession messages.

crates/hotfix/src/session/info.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/// Information about the session's current state.
2+
///
3+
/// This is intended for external code to peek inside
4+
/// the session's internals for debugging and monitoring.
5+
#[derive(Clone, Debug)]
6+
pub struct SessionInfo {
7+
pub next_sender_seq_number: u64,
8+
pub next_target_seq_number: u64,
9+
pub status: Status,
10+
}
11+
12+
/// The status of the session as reported to external consumers.
13+
///
14+
/// These roughly correspond to the `SessionState` variants but don't contain
15+
/// internal state.
16+
#[derive(Clone, Debug)]
17+
pub enum Status {
18+
AwaitingLogon,
19+
AwaitingResend,
20+
AwaitingLogout,
21+
Active,
22+
LoggedOut,
23+
Disconnected,
24+
}

crates/hotfix/src/session/state.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::message::parser::RawFixMessage;
22
use crate::session::event::AwaitingActiveSessionResponse;
3+
use crate::session::info::Status as SessionInfoStatus;
34
use crate::transport::writer::WriterRef;
45
use hotfix_message::message::Message;
56
use std::collections::VecDeque;
@@ -211,6 +212,17 @@ impl SessionState {
211212
pub fn is_expecting_test_response(&self) -> bool {
212213
self.expected_test_response_id().is_some()
213214
}
215+
216+
pub fn as_status(&self) -> SessionInfoStatus {
217+
match self {
218+
SessionState::AwaitingLogon { .. } => SessionInfoStatus::AwaitingLogon,
219+
SessionState::AwaitingResend(_) => SessionInfoStatus::AwaitingResend,
220+
SessionState::AwaitingLogout { .. } => SessionInfoStatus::AwaitingLogout,
221+
SessionState::Active(_) => SessionInfoStatus::Active,
222+
SessionState::LoggedOut { .. } => SessionInfoStatus::LoggedOut,
223+
SessionState::Disconnected(_) => SessionInfoStatus::Disconnected,
224+
}
225+
}
214226
}
215227

216228
#[inline]

0 commit comments

Comments
 (0)