[QFJ-751] Incorrect handling of SequenceReset-GapFill messages when using ResendRequestChunkSize > 0 Created: 18/Jul/13 Updated: 02/Apr/15 Resolved: 28/Mar/14 |
|
Status: | Closed |
Project: | QuickFIX/J |
Component/s: | Engine |
Affects Version/s: | 1.5.3 |
Fix Version/s: | 1.6.0 |
Type: | Bug | Priority: | Default |
Reporter: | Andrzej Hajderek | Assignee: | Christoph John |
Resolution: | Fixed | Votes: | 0 |
Labels: | ResendRequest,, sequence, | ||
Environment: |
FIX 4.4, Initiator, ResendRequestChunkSize = 100 |
Attachments: | log-file.txt SessionTest.java |
Description |
While performing a large session-layer recovery operation (around 1 million of messages) in chunks of 100 the QuickFIX/J engine got stuck, as it ignored a valid GapFill message: 18-07-13 08:56:50.673|QFJ Message Processor|INFO|quickfix: Received SequenceReset FROM: 1000102 TO: 1000103 18-07-13 08:56:50.673|QFJ Message Processor|ERROR|quickfix: MsgSeqNum too high, expecting 1000102 but received 1000103: 8=FIX.4.29=45135=834=100010343=Y49=ABFX52=20130718-08:56:50.66356=TEST_CLIENT122=20130718-00:09:001=B2BUSER60.STP6=0.816711=B2BCLIENT60-1374106069-1000102:014=4000015=EUR17=1374106069-100010220=021=131=0.816732=4000037=B2BCLIENT60-1374106069-1000102:038=4000039=240=D54=155=EUR/GBP60=20130718-00:08:54.57564=20140221109=B2BCLIENT60150=2151=0167=FOR194=0.82195=-0.003285544=GBP5549=AcmecoFXTest6054=32668.00999999=137413781066310=200 After analysis of the Session.nextSequenceReset() method it's clear that the incoming SequenceReset-GapFill message is handled differently when using non-zero ResendRequestChunkSize. Also, it looks like in this particular scenario the target sequence number has not been set (from 1000102) to newSequence (1000103) in the Session.nextSequenceReset() method, because: 1) range[2] was > 0 (which means using non-zero ResendRequestChunkSize) AND 2) newSequence (1000103) was NOT >= range[1] (1084290) AND 3) newSequence (1000103) was NOT >= range[2] (1000200) [All values in the log below.] It looks like the following logic needs to be reviewed because in the discussed scenario the newSequence value was completely ignored: if (range[2] > 0) { else if (newSequence >= range[2]) { state.setNextTargetMsgSeqNum(newSequence + 1); final String beginString = sequenceReset.getHeader().getString( BeginString.FIELD); sendResendRequest(beginString, range[1] + 1, newSequence + 1, range[1]); }} else { state.setNextTargetMsgSeqNum(newSequence); }The log is attached. |
Comments |
Comment by Andrzej Hajderek [ 18/Jul/13 ] |
Attaching the actual log file, as the inline logs look awful. |
Comment by Andrzej Hajderek [ 18/Jul/13 ] |
BTW: Could someone please fix the incorrect tag: "sequnece" (swapped ne). It's used by a bunch of other issues as well. |
Comment by Andrzej Hajderek [ 18/Jul/13 ] |
The following test passes for ResendRequestChunkSize=0, but fails forResendRequestChunkSize=10: // // // boolean isInitiator = true, resetOnLogon = false, validateSequenceNumbers = true; Session session = new Session(new UnitTestApplication(), , UnitTestResponder responder = new UnitTestResponder(); session.logon(); assertEquals(1, session.getStore().getNextTargetMsgSeqNum()); Message logonRequest = new Message(responder.sentMessageData); // Deliver Logon response with too high sequence 20 instead of 1. // The expected target sequence should still be 1. // Deliver the missing message #1. // Deliver the missing message #2. // Deliver SequenceReset-GapFill from 3 to 5 session.next(gapFill); // Deliver the missing message #5.
|
Comment by Andrzej Hajderek [ 19/Jul/13 ] |
Please find attached the updated SessionTest.java source file, which now contains the two new test methods: testSequenceResetGapFillWithZeroChunkSize() and testSequenceResetGapFillWithNonZeroChunkSize() |
Comment by Andrzej Hajderek [ 19/Jul/13 ] |
Not sure why the code I pasted directly got garbled. The attached file is OK. |
Comment by Christoph John [ 28/Mar/14 ] |
Committed as http://sourceforge.net/p/quickfixj/code/1168/ |