[QFJ-457] Acceptor logout trap when the acceptor initiates the logout process Created: 11/Jul/09  Updated: 15/Nov/12  Resolved: 20/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3, 1.4.0, Future Releases
Fix Version/s: 1.5.1

Type: Bug Priority: Critical
Reporter: Stephan Assignee: Eric Deshayes
Resolution: Fixed Votes: 2
Labels: None


 Description   

This bug happens when QuickFixJ is working in acceptor mode.

If the acceptor wants to initiate the logout procedure (send logout message to an initiator), it calls the "logout()" method on the Session.

This sets the boolean "enabled" to false.

public void logout() {
setEnabled(false);
}

Then, the next() method is called by the timer SessionTimerTask. On the first call, it send the logout message to the client because the not enabled, the client is logged on and the logout hasn't been sent yet.

if (!isEnabled()) {
if (isLoggedOn()) {
if (!state.isLogoutSent())

{ getLog().onEvent("Initiated logout request"); generateLogout(state.getLogoutReason()); }
} else { return; }
}

On the next few calls on Session.next(), the timer might eventually disconnect the initiator if not logout response has been received.

if (state.isLogoutTimedOut()) {
getLog().onEvent("Timed out waiting for logout response");
disconnect();
}

The initiator is also disconnected if it send the logout message back.


Until here all is well. Now the problem begins.

Imagine that the same initiator want to reconnect. It sends the Login message to our acceptor. We receive it in the Session.next(Message message) method.
This method will call nextLogon(message) which will generate the logon message.

Then at then end of the next(Message message) method, we call next:

if (isLoggedOn()) {
next();
}


and we are faced once again with the following code which will generate a logout message immediately.

if (!isEnabled()) {
if (isLoggedOn()) {
if (!state.isLogoutSent()) { getLog().onEvent("Initiated logout request"); generateLogout(state.getLogoutReason()); }

} else

{ return; }

}

This happens because the boolean returned by isEnabled() has not been reset to true. So the session is not enabled, it is logged on and not logout has been set yet.

Remember that the enabled boolean was set to false by the acceptor to logout the initiator a moment ago.

Conclusion: the initiator canot logon anymore! It will receive a successful logon response and immediately after a logout message!

The solution is to setEnabled(true) at the login call in case quickfix is in acceptor mode.
In the next(Message message) method change the current code:

if (msgType.equals(MsgType.LOGON)) {
nextLogon(message);
} else if (msgType.equals(MsgType.HEARTBEAT)) {
nextHeartBeat(message);
}
......

for this code:

if (msgType.equals(MsgType.LOGON)) {
if (!state.isInitiator())

{ setEnabled(true); }

nextLogon(message);
} else if (msgType.equals(MsgType.HEARTBEAT)) {
nextHeartBeat(message);
}
......



 Comments   
Comment by Devendra Inamdar [ 12/Mar/10 ]

We are also facing this issue. Is this being addressed?

Comment by Eric Deshayes [ 27/Apr/11 ]

committed on integration branch revision 1022

Comment by Jörg Thönnes [ 20/May/11 ]

Is this bug related?

QFJ-357: Logout message is sent before Logon on each Session start
http://www.quickfixj.org/jira/browse/QFJ-357

Generated at Sat May 11 09:44:27 UTC 2024 using JIRA 7.5.2#75007-sha1:9f5725bb824792b3230a5d8716f0c13e296a3cae.