Imported from previous forum
Is it allowed to send "new" HeartBeats / Test requests while resending "data" in response to
Resend-Request ?
> Is it allowed to send "new" HeartBeats / Test requests while resending "data" in response to
> Resend-Request ?
>
Your counterparty should not be sending heartbeats if it is sending data. If they do send a new heartbeat, it should be thrown away and force a resend from you. They should not resend a heartbeat/testrequest.
Question for others:
What happens if you are not heartbeating during the other side resending, how does the other side force a heartbeat?
[ original email was from Ryan Pierce - rpierce@taltrade.com ]
> > Is it allowed to send "new" HeartBeats / Test requests while resending "data" in response to
> > Resend-Request ?
I don’t know if the spec specifically forbids it. The one explicit requirement I know is that any Resend Request you need to send, should the other party’s Resend Request be out of sequence, be made only after the messages in question are resent.
However, it is not a terribly good practice to interject new messages while resending. Those messages generally cannot be processed, and only serve to slow down eventual recovery. If Party A sends a Resend Request, and party B responds, any interjecting of new messages in the middle of B’s response is going to force A to send yet another Resend Request, slowing down recovery. It is best to treat the response to a Resend Request as an atomic entity; dump the entirety of the messages to be sent on your sending queue, follow them with a Resend Request of your own if Party A’s Resend Request was higher than expected, and then send any new messages like heartbeats, test requests, or business messages.
This really should not be an issue except in the cases of extremely large resends. Party A’s sending of a Resend Request resets Party B’s expected heartbeat timer, so unless B’s reponse to the Resend Request takes longer than the heartbeat interval, A is not going to be late on a heartbeat during that time period, hence B has no reason to send a Test Request. Further, as B resends each message, it should be resetting its own heartbeat timer, so B will never need to send a heartbeat during the resend, regardless of its length. (Provided, of course, that B’s database or message store doesn’t bog down in the middle of the resend, producing a gap greater than the heartbeat interval.)
> Question for others:
>
> What happens if you are not heartbeating during the other side resending, how does the other side force a heartbeat?
There isn’t any effective way to do it. As said above, this is only an issue if the resend takes longer than the heartbeat interval, as your sending the Resend Request will reset the other side’s timer.
Example: you ask for 1 to infinity, and the other side is up to 100,000. You stop sending heartbeats. The other side sends you 1-30,000, which takes 30 seconds. The other side’s next expected sequence number is 100,001. If the other side sent 100,001 Test Request next, there would be a gap. Test Requests are not allowed by the spec to be processed out of sequence, so you’re forced to throw it out and send another resend request from 30,001 - infinity.
Things usually will still recover, although it may take a few tries. In this hypothetical example, in the next 30 seconds, another 30,000 messages are sent, and 2 heartbeat intervals elapse so the connection is severed. The connection comes back up again, and the gap is only from 60,000 to 100,002. The other side sends 60,000 - 90,000, sees that the party is late on a heartbeat, queues 100,003 as a Test Request. 10 seconds later, 90,000 - 100,002 are resent, 100,003 falls into place, the other party responds, and both sides are ready to go.
> There isn’t any effective way to do it. As said above, this is only an issue if the resend takes longer than the heartbeat interval, as your sending the Resend Request will reset the other side’s timer.
>
> Example: you ask for 1 to infinity, and the other side is up to 100,000. You stop sending heartbeats. The other side sends you 1-30,000, which takes 30 seconds. The other side’s next expected sequence number is 100,001. If the other side sent 100,001 Test Request next, there would be a gap. Test Requests are not allowed by the spec to be processed out of sequence, so you’re forced to throw it out and send another resend request from 30,001 - infinity.
>
> Things usually will still recover, although it may take a few tries. In this hypothetical example, in the next 30 seconds, another 30,000 messages are sent, and 2 heartbeat intervals elapse so the connection is severed. The connection comes back up again, and the gap is only from 60,000 to 100,002. The other side sends 60,000 - 90,000, sees that the party is late on a heartbeat, queues 100,003 as a Test Request. 10 seconds later, 90,000 - 100,002 are resent, 100,003 falls into place, the other party responds, and both sides are ready to go.
>
I am not aware of this actually happening and I know in our engine we block new messages during a resend. I was just curious if there was a "best pratice" out there.