Details
Description
From Edward Lee:
Hello,
I've upgraded to QuickFix/J 1.5.1 recently.
However, I encountered an issue regarding the SequenceReset and
synchronziation with other FIX session. I found that the QuickFix cannot
handle more that one SequenceReset when sending out one ResendRequest.
Here is the scenario,
At first, the FIX connection is synchronized and let say the incoming
message seqnum and outgoing message seqnum is both 100.
Now, when I reset both in and out message seqnum to 1. Then, out of sync
happened.
At this moment, I reset the outgoing message seqnum to 100 again.
Then, QuickFix sent out a resendRequest to request message 1 to 100 as it
received a logon message of message seqnum 100.
And then, the counterParty start to resend the message and the sequence is
like below
1. SequenceReset to 31
2. 10 NewOrderSingle
3. SequenceReset to 100
What I can see the behavior of the QuickFix is that it cannot process the
first SequenceReset message and hence, the incoming message seqnum is
still remaining not synchronized.
After checking the source code, I found that the issue is in the
nextSequenceReset method in Session.java as below:
if (newSequence > getExpectedTargetNum()) {
int[] range = state.getResendRange();
if (newSequence >= range[1])
else if (range[2] > 0 && newSequence >= range[2])
{ state.setNextTargetMsgSeqNum(newSequence + 1); String beginString = sequenceReset.getHeader().getString(BeginString.FIELD); sendResendRequest(beginString, range[1] + 1, newSequence+1, range[1]); }} else if (newSequence < getExpectedTargetNum()) {
getLog().onErrorEvent(
"Invalid SequenceReset: newSequence=" +
newSequence + " < expected="
+ getExpectedTargetNum());
if (resetOrDisconnectIfRequired(sequenceReset))
generateReject(sequenceReset,
SessionRejectReason.VALUE_IS_INCORRECT, 0);
}
When the first SequenceReset message comes, the newSequence = 30 and which
is greater than ExpectedTargetNum (i.e. 1)
Then, the range that we get is [1, 100, 0] and the problem came is the
newSequence (30) is not greater than range[1] (i.e. 100), and also
range[2] (i.e. 0) is not greater than 0.
Hence, nothing is done for the SequenceReset message.
I did make a change for the above code to:
if (newSequence > getExpectedTargetNum()) {
int[] range = state.getResendRange();
if (range[2] > 0) {
if (newSequence >= range[1]) { state.setNextTargetMsgSeqNum(newSequence); } else if(newSequence >= range[2]) { state.setNextTargetMsgSeqNum(newSequence + 1); String beginString = sequenceReset.getHeader().getString(BeginString.FIELD); sendResendRequest(beginString, range[1] + 1, newSequence+1, range[1]); }
} else { state.setNextTargetMsgSeqNum(newSequence); }
} else if (newSequence < getExpectedTargetNum()) {
getLog().onErrorEvent(
"Invalid SequenceReset: newSequence=" +
newSequence + " < expected="
+ getExpectedTargetNum());
if (resetOrDisconnectIfRequired(sequenceReset)) { return; }
generateReject(sequenceReset,
SessionRejectReason.VALUE_IS_INCORRECT, 0);
}
And now, I can successfully synchronize.
The question I have is does anyone also encounter this issue? Or did I
miss any config or setup and such that I have this issue?