Uploaded image for project: 'QuickFIX/J'
  1. QuickFIX/J
  2. QFJ-804

Race condition between sessionClosed and processing logout message received

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Default
    • Resolution: Duplicate
    • Affects Version/s: 1.5.3
    • Fix Version/s: 1.6.0
    • Component/s: Build
    • Labels:

      Description

      sessionClosed() called by AbstractIoHandler can call disconnect() on Session before a logout message has been processed by the EventHandlingSession. (This was witnessed with a SingleThreadedEventHandlingStrategy).

      The disconnect() call on Session results in logonSent being set to false in SessionState. If this happens before SingleThreadedEventHandlingStrategy calls next(Message) on the Session object, the logout message will subsequently throw a SessionException in validLogonState() (as logonSent is now false). And the message will not reach the application.

      This is problematic in the scenario where an ECN is informing us in a logout message of an issue with sequence numbers. The message is not received and the appropriate action can't take place,

      This is an example of the occurrence from our logs with Reuters:

      20140731-10:44:42.662 INFO [SocketConnectorIoProcessor-1.0] quickfix.Session - [XXX/YYY->TR MATCHING/FXM] Disconnecting: IO Session closed
      20140731-10:44:42.663 ERROR [QFJ Message Processor] quickfixj.errorEvent - XXX/YYY->TR MATCHING/FXM: quickfix.SessionException Logon state is not valid for message (MsgType=5)

      One possible suggestion would be to check the EventHandlingStrategy queue size and delay the sessionClosed call if there are outstanding events.

      E.g. in InitiatorIoHandler

      @Override
      public void sessionClosed(IoSession ioSession) throws Exception {
      while (eventHandlingStrategy.getQueueSize() > 0) {
      log.info("Delaying sessionClosed while " + eventHandlingStrategy.getQueueSize() + " event(s) "
      + "are processed");
      try

      { Thread.sleep(500); }

      catch (InterruptedException e)

      { log.warn("sessionClosed dealy was interrupted"); }

      }
      super.sessionClosed(ioSession);
      }

      Perhaps there are better approaches. Is this a known race condition?

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                chrjohn Christoph John
                Reporter:
                glyn_walters Glyn Walters
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: