Skip to content

Commit 1ee85d1

Browse files
authored
Merge pull request #160 from bhaan/logout-process
Proper FIX logout sequence
2 parents 1acdf27 + 9075d98 commit 1ee85d1

File tree

3 files changed

+32
-14
lines changed

3 files changed

+32
-14
lines changed

in_session.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ func (state inSession) handleLogon(session *session, msg Message) (nextState ses
7070

7171
func (state inSession) handleLogout(session *session, msg Message) (nextState sessionState) {
7272
session.log.OnEvent("Received logout request")
73-
state.generateLogout(session)
74-
session.application.OnLogout(session.sessionID)
73+
session.log.OnEvent("Sending logout response")
7574

75+
state.generateLogout(session)
7676
return latentState{}
7777
}
7878

@@ -247,6 +247,7 @@ func (state inSession) doTargetTooLow(session *session, msg Message, rej targetT
247247
}
248248

249249
func (state *inSession) initiateLogout(session *session, reason string) (nextState logoutState) {
250+
session.log.OnEvent("Inititated logout request")
250251
state.generateLogoutWithReason(session, reason)
251252
time.AfterFunc(time.Duration(2)*time.Second, func() { session.sessionEvent <- logoutTimeout })
252253

@@ -278,16 +279,15 @@ func (state *inSession) generateLogout(session *session) {
278279
}
279280

280281
func (state *inSession) generateLogoutWithReason(session *session, reason string) {
281-
reply := NewMessage()
282-
reply.Header.SetField(tagMsgType, FIXString("5"))
283-
reply.Header.SetField(tagBeginString, FIXString(session.sessionID.BeginString))
284-
reply.Header.SetField(tagTargetCompID, FIXString(session.sessionID.TargetCompID))
285-
reply.Header.SetField(tagSenderCompID, FIXString(session.sessionID.SenderCompID))
282+
logout := NewMessage()
283+
logout.Header.SetField(tagMsgType, FIXString("5"))
284+
logout.Header.SetField(tagBeginString, FIXString(session.sessionID.BeginString))
285+
logout.Header.SetField(tagTargetCompID, FIXString(session.sessionID.TargetCompID))
286+
logout.Header.SetField(tagSenderCompID, FIXString(session.sessionID.SenderCompID))
286287

287288
if reason != "" {
288-
reply.Body.SetField(tagText, FIXString(reason))
289+
logout.Body.SetField(tagText, FIXString(reason))
289290
}
290291

291-
session.send(reply)
292-
session.log.OnEvent("Sending logout response")
292+
session.send(logout)
293293
}

logout_state.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,25 @@ func (state logoutState) String() string { return "Logout State" }
77
func (s logoutState) IsLoggedOn() bool { return false }
88

99
func (state logoutState) FixMsgIn(session *session, msg Message) (nextState sessionState) {
10-
return state
10+
var msgType FIXString
11+
if err := msg.Header.GetField(tagMsgType, &msgType); err != nil {
12+
return latentState{}
13+
}
14+
15+
switch string(msgType) {
16+
//logout
17+
case "5":
18+
session.log.OnEvent("Received logout response")
19+
return latentState{}
20+
default:
21+
return state
22+
}
1123
}
1224

1325
func (state logoutState) Timeout(session *session, event event) (nextState sessionState) {
1426
switch event {
1527
case logoutTimeout:
16-
session.log.OnEvent("Timed out waiting for Logout response")
28+
session.log.OnEvent("Timed out waiting for logout response")
1729
return latentState{}
1830
}
1931

session.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ func (s *session) handleLogon(msg Message) error {
311311

312312
s.log.OnEvent("Responding to logon request")
313313
s.send(reply)
314+
} else {
315+
s.log.OnEvent("Received logon response")
314316
}
315317

316318
s.application.OnLogon(s.sessionID)
@@ -565,8 +567,12 @@ func (s *session) run(msgIn chan fixIn, msgOut chan []byte, quit chan bool) {
565567
s.peerTimer.Reset(time.Duration(int64(1.2 * float64(s.heartBeatTimeout))))
566568

567569
case <-quit:
568-
return
569-
570+
quit = nil // prevent infinitly receiving on a closed channel
571+
if state, ok := s.sessionState.(inSession); ok {
572+
s.sessionState = state.initiateLogout(s, "")
573+
} else {
574+
return
575+
}
570576
case evt := <-s.sessionEvent:
571577
s.sessionState = s.Timeout(s, evt)
572578
case <-s.messageEvent:

0 commit comments

Comments
 (0)