How to manage sessions in FIX Antenna HFT

Overview

This article is intended to describe session management: creation, reconnection, and disconnection of the session in FIX Antenna HFT.

Session creation

There are three cases of the session creation:

  • Create all sessions at the service start
  • Create a session on the fly as needed
  • Create a session on demand as an unregistered acceptor if the engine.properties file is configured to allow this. The UnregisteredAcceptor.CreateSession property must be set to 'true'.

In the first two cases a session is created ahead and in the last case the engine has to allocate all resources only when a Logon message is received.

Resources allocation is quite a heavy operation and one shouldn't use engine's threads in the callbacks to create a session. Creation of the session on demand as unregistered acceptor is performed in a separate thread - one of the engine's general purpose workers.

The reason to create sessions ahead is to better control the sessions' parameters. Only defaults can be applied in case of unregistered acceptors.

When a session is created ahead and is not used, it consumes memory and file descriptors but does not consume CPU resources.

Create session ahead

The following piece of code shows the creation of the session ahead:

//create ahead:
ssn = FixEngine::singleton()->createSession( application, "Sender", "Target", FIX44 )
if( asAcceptor )
      ssn->connect();
else //as initiator
      ssn->connect(hbi, host, port);

Create session on demand

The following piece of code shows the creation of the session on demand:

//create by demand (one should allow unregistered acceptors in the engine config)
// implement SessionsManager interface
class MySessionsManager : public Engine::SessionsManager
//....
//register manager
MySessionsManager* g_mySM = new MySessionsManager();
Engine::FixEngine::InitParameters params;
params.sessionsManager_ = g_mySM;
FixEngine::init( params );
//make descision accept or deny incomiing unregistered session
bool MySessionsManager::onUnregisteredAcceptor( Engine::Session* apSn, const FIXMessage& /*logonMsg*/ )
{
   if( passUserCheck( apSn ) {
          apSn->registerApplication( application );
          apSn->addRef(); //increase count of session users
          return true; // accept
   }
   return false; //deny
}

Once the session is created it becomes registered and the onUnregisteredAcceptor callback won't be called until the full session is destroyed, so one should use ssn->connect() to activate this session.

Session storage will be loaded and SeqNums will be continued for unregistered acceptors even after the session destruction when session storage logs are accessible for the engine.

Session disconnection

  • Non-graceful disconnection without a Logout message - just drop the TCP link: ssn → disconnectNonGracefully(). When the counterparty disconnects without sending a Logout then the onLogoutEvent() callback is not called for the session. The onNewStateEvent() callback should be used in this situation.
  • Graceful disconnection with a Logout message: ssn → disconnect(reason). It is needed to take additional actions to check whether the session is finally disconnected. The session state should become Session::CORRECTLY_TERMINATED or Session::NON_GRACEFULLY_TERMINATED.

When a session is configured to continue SeqNums on the next connect (via the IntradayLogoutTolerance property) it will be marked as Session::NON_GRACEFULLY_TERMINATED even if the Logout message is received.

The following piece of code shows the session disconnection with the session release:

  ssn->disconnect( logoutReason );
        Session::State st = session->getState();
        while( Session::CORRECTLY_TERMINATED != session->getState() && 
               Session::NON_GRACEFULLY_TERMINATED != session->getState())
        {
            sleepns(10*1000*1000);
            st = session->getState();
        }
        session->release();

Session reconnection

Acceptor

According to the FIX protocol standard when connection is terminated unexpectedly, the acceptor is moved to the 'Wait for logon' state. It is expected that the initiator on the remote side re-establishes telecommunication link and sends FIX Logon message continuing sequence numbers. When the correct Logon message is received, it is accepted by the engine and the session acceptor continues working from the point of termination.

Initiator

In the case that the initiator FIX-session is disconnected non-gracefully there is a way to enable automatic reconnection to be able to reconnect as soon as the server or the connection is available again. The reconnection count can be set to -1 in the engine.properties file to make infinite reconnection attempts.

engine.properties
ForcedReconnect = true
ReconnectMaxTries = -1
ReconnectInterval = 5

To interrupt reconnection the Session::disconnectNonGracefully method is called.