Resending Messages
When the Resend Request message is received from the counterparty (e.g., due to a sequence number mismatch), the ResendingStarted event is raised first, which indicates the session is about to start resending messages. Then the MessageResending event is raised for each resending message if the application has been subscribed to this event. Otherwise, the SequenceReset-GapFill message will be sent instead of the requested message.
If the sent application-level message needs to be resent to the counterparty, then the
AllowResending property of MessageResendingEventArgs parameter should be set to true
while handling the event.
Otherwise, the SequenceReset-GapFill message will be sent instead (e.g., in case of an old order).
The message that is about to be resent is available via the Message property of the MessageResendingEventArgs parameter.
When the resending process is completed, the ResendingFinished event is raised.
For example:
var session = new Session("SenderCompID", "TargetCompID", ProtocolVersion.Fix44);
session.ResendingStarted += OnResendingStarted;
session.ResendingFinished += OnResendingFinished;
session.MessageResending += OnMessageResending;
void OnResendingStarted(object sender, ResendingStartedFinishedEventArgs e)
{
Console.WriteLine("ResendRequest (MsgType=2) message is received and the session is about to start resending messages from sequence number {0} to {1}", e.BeginSeqNo, e.EndSeqNo);
};
void OnResendingFinished(object sender, ResendingStartedFinishedEventArgs e)
{
Console.WriteLine("Resending process is completed");
};
void OnMessageResending(object sender, MessageResendingEventArgs e)
{
Console.WriteLine("Resend request for message {0}", e.Message);
e.AllowResending = !IsStale(e.Message);
Console.WriteLine("AllowResending=" + e.AllowResending);
}
bool IsStale(Message message)
{
// Simple sending time-based filtering of stale messages.
DateTime previousSendingTime = message.GetTimestamp(Tag.SendingTime);
TimeSpan threshold = TimeSpan.FromMinutes(30);
return (DateTime.UtcNow - previousSendingTime) > threshold;
// More advanced filtering could take into account the message type and/or application-level content.
}
Resending Queue Size
The ResendingQueueSize parameter specifies how much messages can be resent if counterparty will request them. For example, this parameter is
set to 1000
, and 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 with sequence numbers from 1001
to 2000
will be resent.
If this parameter is zero, no messages will be resent.
Message Gap Handling Modes
Per the FIX protocol there are two options for dealing with gaps:
- Request all messages including the last message received.
- Request for the specific message missed while maintaining an ordered list of all newer messages.
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 Resend Request for all messages and waits for the reply. All newer incoming messages are ignored until the reply is received. To report the new messages anyway, use the ReportNewMessagesWhileWaitingForMissedMessages property. After the reply is received (first message with the PossDupFlag 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.
To activate the second option of the resend functionality, set the RequestOnlyMissedMessages property to true
.
In this mode, when a sequence gap is detected, the FIX Engine sends the
Resend Request 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.
To limit the size of this queue, use the IncomingMessageGapQueueMaximumSize setting.
Process Large Sequence Numbers Intervals of Resend Requests
The resending process can take time, especially if the number of resending messages is large. During the resend process, the session reads sending messages from the summary log file, deserializes them, and resends them to the counterparty. This process is thread-safe and is executed under the session's lock. As a result, session methods can be blocked until the resend process is completed. Therefore, it makes sense not to call the session's methods and not to pressure the session by sending new messages during this period. ResendingStarted/ResendingFinished events can be used to detect the start/finish of the resending process and implement the necessary logic. Additionally, one can use the ResendingBatchSize setting. It allows to set the maximum number of messages sent in reply to the Resend Request(2) before temporarily releasing the session’s lock.
See Also
- The ResendingMessages sample from the FIX Engine distribution package