It is resend time again

Imported from previous forum

We have an interesting difference of opinion with a counterparty.

Please consider the following scenario :

A session has been established, our side transmits a heartbeat, sequence nr 2001. Our counterparty asks for a resend 1000 - 2000. Our side sends 1000 - 1500. Then the resend is stopped, due to TCP window size, a socket operation would block. After hearbeat interval, our side sends a heartbeat, sequence nr 2002. Our side expects a resend 1501-2002 from the counterparty in this situation quoting the following fix specifications:

"When the incoming sequence number does not match the expected number corrective processing is required."

Our counterparty does not agree with this, they accept the heartbeat by saying the sequence number is as expected.

Can someone confirm that our expectation for a resend 1501-2002 in this case is reasonable.

They should generated a ResendRequest with BeginSeqNo of 1501. However, I don’t quite understand why you can’t fulfill the resend request after the socket was no longer blocked. It’s obviously not blocked if you can send a heartbeat after the heartbeat interval gracefully. We recommend using the infinity value for EndSeqNo on resend requests as well.

> We have an interesting difference of opinion with a counterparty.
>
> Please consider the following scenario :
>
> A session has been established, our side transmits a heartbeat, sequence nr 2001. Our counterparty asks for a resend 1000 - 2000. Our side sends 1000 - 1500. Then the resend is stopped, due to TCP window size, a socket operation would block. After hearbeat interval, our side sends a heartbeat, sequence nr 2002. Our side expects a resend 1501-2002 from the counterparty in this situation quoting the following fix specifications:
>
> "When the incoming sequence number does not match the expected number corrective processing is required."
>
> Our counterparty does not agree with this, they accept the heartbeat by saying the sequence number is as expected.
>
> Can someone confirm that our expectation for a resend 1501-2002 in this case is reasonable.
>
>

Wilbert:
1501-2002 is reasonable, I think.
Have to cover the gap from the missed num to the num of last seq num.
Scott’s advice is considerate enough to avoid possible misunderstanding. We will take it in ours.
Thanks.

> They should generated a ResendRequest with BeginSeqNo of 1501. However, I don’t quite understand why you can’t fulfill the resend request after the socket was no longer blocked. It’s obviously not blocked if you can send a heartbeat after the heartbeat interval gracefully. We recommend using the infinity value for EndSeqNo on resend requests as well.
>
>
> > We have an interesting difference of opinion with a counterparty.
> >
> > Please consider the following scenario :
> >
> > A session has been established, our side transmits a heartbeat, sequence nr 2001. Our counterparty asks for a resend 1000 - 2000. Our side sends 1000 - 1500. Then the resend is stopped, due to TCP window size, a socket operation would block. After hearbeat interval, our side sends a heartbeat, sequence nr 2002. Our side expects a resend 1501-2002 from the counterparty in this situation quoting the following fix specifications:
> >
> > “When the incoming sequence number does not match the expected number corrective processing is required.”
> >
> > Our counterparty does not agree with this, they accept the heartbeat by saying the sequence number is as expected.
> >
> > Can someone confirm that our expectation for a resend 1501-2002 in this case is reasonable.
> >
> >
>

[ original email was from Ryan Pierce - rpierce@taltrade.com ]
> A session has been established, our side transmits a heartbeat, sequence nr 2001. Our counterparty asks for a resend 1000 - 2000. Our side sends 1000 - 1500. Then the resend is stopped, due to TCP window size, a socket operation would block. After hearbeat interval, our side sends a heartbeat, sequence nr 2002. Our side expects a resend 1501-2002 from the counterparty in this situation quoting the following fix specifications:
>
> "When the incoming sequence number does not match the expected number corrective processing is required."
>
> Our counterparty does not agree with this, they accept the heartbeat by saying the sequence number is as expected.
>
> Can someone confirm that our expectation for a resend 1501-2002 in this case is reasonable.

I do not believe either of you are doing the right thing.

You are not properly responding to the Resend Request. I understand the issue of the operating system’s TCP buffer filling, but FIX engines often get around the issue by buffering the data inside the application itself, appending new messages to the end of the buffer when the buffer is full, and sending sequentially from the buffer. In order to prevent infinite memory useage in the case of a client that is getting progressively behind, you may choose to limit the number of bytes queued in that buffer; at a certain point you declare the connection dead and close it.

I’ve implemented this in Win32 C++ by setting the socket to non-blocking mode with ioctlsocket() using FIONBIO. I assume you could use ioctl() in Unix to do the same thing. Then, whenever I call send(), I check for errors (WSAEWOULDBLOCK in Win32 or EAGAIN / EWOULDBLOCK in Unix indicates the OS’s TCP buffer is full) or the number of bytes written (which may indicate that either all, or only some, of the message is written, and manage my internal buffer accordingly.

Yes, I understand that this can be complex, especially the boundary condition cases and the issue of what happens when only part of a message gets sent in the send() call. But trading activity can often be notoriously bursty, exceeding the TCP buffer size the operating system allows. Hence I would consider just dropping any data sent when the TCP buffer is full to be a severe handicap in an engine.

However, from what you’ve posted, the other party appears to be wrong as well in ignoring all those messages instead of sending a Resend Request.