@@ -392,7 +392,9 @@ where
392392 }
393393
394394 if self . state . is_logged_on ( ) {
395- self . send_logout ( "Logout acknowledged" ) . await ?;
395+ self . state
396+ . send_logout ( & mut self . ctx , "Logout acknowledged" )
397+ . await ?;
396398 }
397399
398400 self . ctx
@@ -649,10 +651,12 @@ where
649651 }
650652
651653 async fn handle_incorrect_begin_string ( & mut self , received_begin_string : String ) {
652- self . logout_and_terminate ( & format ! (
653- "beginString={received_begin_string} is not supported"
654- ) )
655- . await ;
654+ self . state
655+ . logout_and_terminate (
656+ & mut self . ctx ,
657+ & format ! ( "beginString={received_begin_string} is not supported" ) ,
658+ )
659+ . await ;
656660 }
657661
658662 async fn handle_incorrect_comp_id (
@@ -671,7 +675,8 @@ where
671675 error ! ( "failed to send reject message with invalid comp ID: {err}" ) ;
672676 } ;
673677
674- self . logout_and_terminate ( "incorrect comp ID received" )
678+ self . state
679+ . logout_and_terminate ( & mut self . ctx , "incorrect comp ID received" )
675680 . await ;
676681 }
677682
@@ -691,7 +696,9 @@ where
691696 "we expected {expected} sequence number, but target sent lower ({actual}), terminating..."
692697 ) ;
693698 let reason = format ! ( "sequence number too low (actual {actual}, expected {expected})" ) ;
694- self . logout_and_terminate ( & reason) . await ;
699+ self . state
700+ . logout_and_terminate ( & mut self . ctx , & reason)
701+ . await ;
695702 self . state = SessionState :: new_disconnected ( false , & reason) ;
696703 }
697704
@@ -817,11 +824,7 @@ where
817824 & mut self ,
818825 message : impl OutboundMessage ,
819826 ) -> Result < u64 , InternalSendError > {
820- let msg_type = message. message_type ( ) . to_string ( ) ;
821- let prepared = self . ctx . prepare_message ( message) . await ?;
822- self . state . send_message ( & msg_type, prepared. raw ) . await ;
823- self . reset_heartbeat_timer ( ) ;
824- Ok ( prepared. seq_num )
827+ self . state . send_message ( & mut self . ctx , message) . await
825828 }
826829
827830 async fn send_resend_request (
@@ -850,48 +853,6 @@ where
850853 Ok ( ( ) )
851854 }
852855
853- async fn send_logout ( & mut self , reason : & str ) -> Result < ( ) , SessionOperationError > {
854- let logout = Logout :: with_reason ( reason. to_string ( ) ) ;
855- self . send_message ( logout)
856- . await
857- . with_send_context ( "logout" ) ?;
858- Ok ( ( ) )
859- }
860-
861- /// Sends a logout message and immediately disconnects the counterparty.
862- ///
863- /// This should be used sparingly in scenarios where there is a major issue
864- /// requiring operational intervention, such as the sequence number being lower
865- /// than expected, or some other key header field containing an invalid value.
866- ///
867- /// In other scenarios, [`initiate_graceful_logout`] should be preferred.
868- async fn logout_and_terminate ( & mut self , reason : & str ) {
869- if let Err ( err) = self . send_logout ( reason) . await {
870- warn ! ( "failed to send logout during session termination: {}" , err) ;
871- }
872- self . state . disconnect_writer ( ) . await ;
873- }
874-
875- /// Sends a logout message and puts the session state into an [`AwaitingLogout`] state.
876- ///
877- /// The session waits for a configurable timeout period for the counterparty to
878- /// respond with a `Logout` message. If no response is received within the timeout
879- /// period, it disconnects the counterparty.
880- async fn initiate_graceful_logout (
881- & mut self ,
882- reason : & str ,
883- reconnect : bool ,
884- ) -> Result < ( ) , SessionOperationError > {
885- if self . state . try_transition_to_awaiting_logout (
886- Duration :: from_secs ( self . ctx . config . logout_timeout ) ,
887- reconnect,
888- ) {
889- self . send_logout ( reason) . await ?;
890- }
891-
892- Ok ( ( ) )
893- }
894-
895856 async fn handle_session_event ( & mut self , event : SessionEvent ) {
896857 self . handle_schedule_check ( ) . await ;
897858
@@ -900,7 +861,9 @@ where
900861 if let Err ( err) = self . on_incoming ( fix_message) . await {
901862 let reason = err. to_string ( ) ;
902863 error ! ( reason, "fatal error in message processing" ) ;
903- self . logout_and_terminate ( "internal error" ) . await ;
864+ self . state
865+ . logout_and_terminate ( & mut self . ctx , "internal error" )
866+ . await ;
904867 self . state = SessionState :: new_disconnected ( true , & reason) ;
905868 }
906869 }
@@ -945,7 +908,8 @@ where
945908 AdminRequest :: InitiateGracefulShutdown { reconnect } => {
946909 warn ! ( "initiating shutdown on request from admin.." ) ;
947910 if let Err ( err) = self
948- . initiate_graceful_logout ( "explicitly requested" , reconnect)
911+ . state
912+ . initiate_graceful_logout ( & mut self . ctx , "explicitly requested" , reconnect)
949913 . await
950914 {
951915 error ! ( err = ?err, "initiating graceful shutdown" ) ;
@@ -973,7 +937,9 @@ where
973937 async fn handle_peer_timeout ( & mut self ) {
974938 if self . state . is_expecting_test_response ( ) {
975939 warn ! ( "peer didn't respond, terminating.." ) ;
976- self . logout_and_terminate ( "peer timeout" ) . await ;
940+ self . state
941+ . logout_and_terminate ( & mut self . ctx , "peer timeout" )
942+ . await ;
977943 } else if self . state . is_awaiting_logon ( ) {
978944 warn ! ( "peer didn't respond to our Logon, disconnecting.." ) ;
979945 self . state . disconnect_writer ( ) . await ;
@@ -1007,7 +973,9 @@ where
1007973 Ok ( SessionPeriodComparison :: DifferentPeriod ) => {
1008974 // the message store is for a previous session,
1009975 // we need to terminate this session, reset the store, and reestablish the session
1010- self . logout_and_terminate ( "session period changed" ) . await ;
976+ self . state
977+ . logout_and_terminate ( & mut self . ctx , "session period changed" )
978+ . await ;
1011979 if let Err ( err) = self . ctx . store . reset ( ) . await {
1012980 error ! ( "error resetting session store: {err:}" ) ;
1013981 self . state =
@@ -1018,7 +986,8 @@ where
1018986 // the creation_time was recorded outside the session schedule,
1019987 // treat this similarly to a different period - reset the store
1020988 warn ! ( "store creation time is outside session schedule, resetting store" ) ;
1021- self . logout_and_terminate ( "creation time outside schedule" )
989+ self . state
990+ . logout_and_terminate ( & mut self . ctx , "creation time outside schedule" )
1022991 . await ;
1023992 if let Err ( err) = self . ctx . store . reset ( ) . await {
1024993 error ! ( "error resetting session store: {err:}" ) ;
@@ -1029,13 +998,16 @@ where
1029998 Err ( err) => {
1030999 // actual schedule calculation error (e.g., DST transition, date overflow)
10311000 error ! ( "error checking session period: {err:?}" ) ;
1032- self . logout_and_terminate ( "internal error" ) . await ;
1001+ self . state
1002+ . logout_and_terminate ( & mut self . ctx , "internal error" )
1003+ . await ;
10331004 }
10341005 }
10351006 } else if self . state . is_connected ( ) {
10361007 // we are currently outside scheduled session time
10371008 if let Err ( err) = self
1038- . initiate_graceful_logout ( "End of session time" , true )
1009+ . state
1010+ . initiate_graceful_logout ( & mut self . ctx , "End of session time" , true )
10391011 . await
10401012 {
10411013 error ! ( err = ?err, "failed to initiate graceful logout" ) ;
0 commit comments