Skip to content

Commit 4f687f4

Browse files
committed
Add handle_verification_issue to AwaitingLogout and AwaitingLogon state
1 parent 068b3da commit 4f687f4

2 files changed

Lines changed: 83 additions & 0 deletions

File tree

crates/hotfix/src/session/state/awaiting_logon.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1+
use crate::Application;
2+
use crate::message::resend_request::ResendRequest;
3+
use crate::session::ctx::{SessionCtx, TransitionResult};
4+
use crate::session::error::{InternalSendResultExt, SessionOperationError};
5+
use crate::session::inbound::{self, VerificationOutcome};
6+
use crate::session::outbound;
7+
use crate::session::state::{AwaitingResendState, SessionState};
18
use crate::transport::writer::WriterRef;
9+
use hotfix_message::message::Message;
10+
use hotfix_store::MessageStore;
211
use tokio::time::Instant;
12+
use tracing::debug;
313

414
pub(crate) struct AwaitingLogonState {
515
/// The writer's reference to send messages to the counterparty
@@ -9,3 +19,40 @@ pub(crate) struct AwaitingLogonState {
919
/// When we are expecting the Logon response at the latest
1020
pub(crate) logon_timeout: Instant,
1121
}
22+
23+
impl AwaitingLogonState {
24+
pub(crate) async fn handle_verification_issue<A: Application, S: MessageStore>(
25+
&self,
26+
ctx: &mut SessionCtx<A, S>,
27+
message: &Message,
28+
check_too_high: bool,
29+
check_too_low: bool,
30+
) -> Result<TransitionResult, SessionOperationError> {
31+
match inbound::verify_and_handle_errors(
32+
ctx,
33+
&self.writer,
34+
message,
35+
check_too_high,
36+
check_too_low,
37+
)
38+
.await
39+
{
40+
VerificationOutcome::Ok => Ok(TransitionResult::Stay),
41+
VerificationOutcome::Handled(result) => Ok(result),
42+
VerificationOutcome::SequenceGap { expected, actual } => {
43+
debug!(
44+
"we are behind target (ours: {expected}, theirs: {actual}), requesting resend."
45+
);
46+
let awaiting_resend =
47+
AwaitingResendState::new(self.writer.clone(), expected, actual);
48+
let request = ResendRequest::new(expected, actual);
49+
outbound::send_message(ctx, &self.writer, request)
50+
.await
51+
.with_send_context("resend request")?;
52+
Ok(TransitionResult::TransitionTo(
53+
SessionState::AwaitingResend(awaiting_resend),
54+
))
55+
}
56+
}
57+
}
58+
}

crates/hotfix/src/session/state/awaiting_logout.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
use crate::Application;
2+
use crate::session::ctx::{SessionCtx, TransitionResult};
3+
use crate::session::error::SessionOperationError;
4+
use crate::session::inbound::{self, VerificationOutcome};
15
use crate::transport::writer::WriterRef;
6+
use hotfix_message::message::Message;
7+
use hotfix_store::MessageStore;
28
use tokio::time::Instant;
9+
use tracing::warn;
310

411
pub(crate) struct AwaitingLogoutState {
512
/// The writer's reference to send messages to the counterparty
@@ -9,3 +16,32 @@ pub(crate) struct AwaitingLogoutState {
916
/// Indicates whether we should attempt to reconnect after we've fully logged out
1017
pub(crate) reconnect: bool,
1118
}
19+
20+
impl AwaitingLogoutState {
21+
pub(crate) async fn handle_verification_issue<A: Application, S: MessageStore>(
22+
&self,
23+
ctx: &mut SessionCtx<A, S>,
24+
message: &Message,
25+
check_too_high: bool,
26+
check_too_low: bool,
27+
) -> Result<TransitionResult, SessionOperationError> {
28+
match inbound::verify_and_handle_errors(
29+
ctx,
30+
&self.writer,
31+
message,
32+
check_too_high,
33+
check_too_low,
34+
)
35+
.await
36+
{
37+
VerificationOutcome::Ok => Ok(TransitionResult::Stay),
38+
VerificationOutcome::Handled(result) => Ok(result),
39+
VerificationOutcome::SequenceGap { expected, actual } => {
40+
warn!(
41+
"sequence gap detected while awaiting logout (expected {expected}, actual {actual}), ignoring"
42+
);
43+
Ok(TransitionResult::Stay)
44+
}
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)