Skip to content

Commit 368014d

Browse files
committed
Refactor to push action to set target sequence number into state which knows what state it's valid for
1 parent 9537b07 commit 368014d

2 files changed

Lines changed: 38 additions & 17 deletions

File tree

crates/hotfix/src/session.rs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -569,22 +569,13 @@ where
569569
self.reset_on_next_logon = true;
570570
}
571571
AdminRequest::SetNextTargetSeqNum { seq_num, responder } => {
572-
let current = self.state.as_status();
573-
let response = if matches!(self.state, SessionState::Disconnected(_)) {
574-
self.ctx
575-
.store
576-
.set_target_seq_number(seq_num.get() - 1)
577-
.await
578-
.map_err(SetNextTargetSeqNumError::from)
579-
} else {
580-
warn!(
581-
?current,
582-
seq_num = seq_num.get(),
583-
"rejecting SetNextTargetSeqNum outside Disconnected state"
584-
);
585-
Err(SetNextTargetSeqNumError::InvalidState { current })
586-
};
587-
572+
let response = self
573+
.state
574+
.try_set_next_target_seq_num(&mut self.ctx, seq_num)
575+
.await;
576+
if let Err(ref err) = response {
577+
warn!(?err, seq_num = seq_num.get(), "SetNextTargetSeqNum rejected");
578+
}
588579
if responder.send(response).is_err() {
589580
error!("failed to respond to SetNextTargetSeqNum request");
590581
}

crates/hotfix/src/session/state.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ use crate::message::logon::Logon;
1616
use crate::message::logout::Logout;
1717
use crate::message::verification::VerificationFlags;
1818
use crate::session::ctx::{PreProcessDecision, SessionCtx, TransitionResult, VerificationResult};
19-
use crate::session::error::{InternalSendError, InternalSendResultExt, SessionOperationError};
19+
use crate::session::error::{
20+
InternalSendError, InternalSendResultExt, SessionOperationError, SetNextTargetSeqNumError,
21+
};
2022
use crate::session::event::ScheduleResponse;
2123
use crate::session::info::Status as SessionInfoStatus;
2224
use crate::transport::writer::WriterRef;
2325
use hotfix_message::message::Message;
2426
use hotfix_store::MessageStore;
27+
use std::num::NonZeroU64;
2528
use std::time::Duration;
2629
use tokio::sync::oneshot;
2730
use tokio::time::Instant;
@@ -247,6 +250,33 @@ impl SessionState {
247250
}
248251
}
249252

253+
/// Set the next expected target sequence number. Only permitted while
254+
/// `Disconnected` — any other state returns `InvalidState`.
255+
///
256+
/// The store stores "last seen" (see `inbound::on_sequence_reset` passing
257+
/// `end - 1`), so we subtract 1 to make `next_target_seq_number()` return
258+
/// `seq_num`. `NonZeroU64` guarantees the subtraction is safe.
259+
pub(crate) async fn try_set_next_target_seq_num<A, S>(
260+
&self,
261+
ctx: &mut SessionCtx<A, S>,
262+
seq_num: NonZeroU64,
263+
) -> Result<(), SetNextTargetSeqNumError>
264+
where
265+
A: Application,
266+
S: MessageStore,
267+
{
268+
match self {
269+
SessionState::Disconnected(_) => ctx
270+
.store
271+
.set_target_seq_number(seq_num.get() - 1)
272+
.await
273+
.map_err(SetNextTargetSeqNumError::from),
274+
_ => Err(SetNextTargetSeqNumError::InvalidState {
275+
current: self.as_status(),
276+
}),
277+
}
278+
}
279+
250280
/// Sends a logout message and puts the session state into an [`AwaitingLogout`] state.
251281
///
252282
/// The session waits for a configurable timeout period for the counterparty to

0 commit comments

Comments
 (0)