OnixS C++ FIX Engine  3.25.0
API Documentation
Resending Messages

When the Resend Request (2) message is received from the counterparty (e.g. due to a sequence number mismatch), the OnixS::FIX::ISessionListener::onResendRequest method is called, if an application has been previously subscribed to listening to session events. Otherwise, the SequenceReset-GapFill (4) message will be sent instead of the requested message.

If the sent application-level message should not to be resent to the counterparty, then the overridden OnixS::FIX::ISessionListener::onResendRequest must return false. In this case, the SequenceReset-GapFill (4) message will be sent instead (e.g. in case of an aged/stale order).

The message, that is about to be resent, is available as a read only parameter in the OnixS::FIX::ISessionListener::onResendRequest signature.

Under what conditions might FIX Engine send a Resend Request (35=2)?

FIX Engine will send Resend Request (2) message, if sequence number of incoming message is greater than expected.

Note
According to the FIX specification, Resend Request (2) is sent by the receiving application to initiate the retransmission of messages. This function is utilized if a sequence number gap is detected, if the receiving application lost a message, or as a function of the initialization process.

Resending queue size

There is one important parameter: OnixS::FIX::EngineSettings::resendingQueueSize. This parameter will specify how much messages can be resent if a counterparty requests them. For example, this parameter is set to 1000, and the counterparty sends a ResendRequest message with sequence numbers rage 1-2000. In this case, the session will send a SequenceReset-GapFill (4) message for range 1-1000, and messages 1001-2000 will be resent. If this parameter is zero, no messages will be resent.

Two options of the resend functionality when the sequence gap is detected

In accordance with the FIX protocol there are two options for dealing with gaps:

The default behavior of the FIX Engine corresponds to the first option. In this mode, when a sequence gap is detected, the FIX Engine sends the Resend Request (2) for all messages and waits for the reply. All newer incoming messages are ignored until the reply is received. In order to report the new messages anyway you can use OnixS::FIX::Session::reportNewMessagesWhileWaitingForMissedMessages setting. After the reply is received (first message with the PossDupFlag (tag #43) flag), there should not be any newer original messages until all requested messages are received, otherwise each such a message will cause a new resend request. Therefore, it can increase the network load and make difficulties for the sequence synchronization.

In order to activate the second option of the resend functionality you need to set the OnixS::FIX::Session::requestOnlyMissedMessages setting to true. In this mode, when a sequence gap is detected, the FIX Engine sends the Resend Request (2) only for missed messages. All newer incoming messages are stored in the incoming message gap queue and they are processed when all requested messages are received. You can limit the size of this queue by the OnixS::FIX::Session::incomingMessageGapQueueMaximumSize setting.

To check all aspects of the resend functionality one may run the ResendingMessages sample from the FIX Engine distribution package.

Code Example

bool isStale (const Message& message)
{
// Simple sending time based filtering of stale messages.
Timestamp previousSendingTime = message.getTimestamp (Tags::SendingTime);
long long keepingTime = 30 * 60; // 30 minutes
bool isStale = (Timestamp::utc ().totalSeconds () - previousSendingTime.totalSeconds ()) >= keepingTime;
return isStale;
// More advanced filtering could take into account the message type and/or application-level contents.
}
bool onResendRequest (Message& message, Session* session)
{
std::cout << "Resend request for message "<< message << std::endl;
bool allowResending = !isStale (message);
std::cout << "AllowResending=" << (allowResending ? "true" : "false") << std::endl;
return allowResending;
}