[QFJ-554] SleepycatStore can enter infinite loop retrieving messages for resend. Created: 26/Aug/10  Updated: 26/Aug/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: James Olsen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

SleepycatStore does not check returned OperationStatus from call to com.sleepycat.je.Cursor.getNext(...):

public synchronized void get(int startSequence, int endSequence, Collection<String> messages) throws IOException {
...
if (retVal == OperationStatus.NOTFOUND)

{ log.debug(sequenceKey + "/" + messageBytes + " not matched in database " + messageDatabase.getDatabaseName()); return; } else {
Integer sequenceNumber = (Integer) sequenceBinding.entryToObject(sequenceKey);
while (sequenceNumber.intValue() <= endSequence) {
messages.add(new String(messageBytes.getData(), charsetEncoding));
if (log.isDebugEnabled()) { log.debug("Found record " + sequenceNumber + "=>" + new String(messageBytes.getData(), charsetEncoding) + " for search key/data: " + sequenceKey + "=>" + messageBytes); }
cursor.getNext(sequenceKey, messageBytes, LockMode.DEFAULT);
sequenceNumber = (Integer) sequenceBinding.entryToObject(sequenceKey);
}
}
...
}

Should be:

public synchronized void get(int startSequence, int endSequence, Collection<String> messages) throws IOException {
...
if (retVal == OperationStatus.NOTFOUND) { log.debug(sequenceKey + "/" + messageBytes + " not matched in database " + messageDatabase.getDatabaseName()); return; }

else {
Integer sequenceNumber = (Integer) sequenceBinding.entryToObject(sequenceKey);
while (retVal == OperationStatus.SUCCESS && sequenceNumber.intValue() <= endSequence) {
messages.add(new String(messageBytes.getData(), charsetEncoding));
if (log.isDebugEnabled())

{ log.debug("Found record " + sequenceNumber + "=>" + new String(messageBytes.getData(), charsetEncoding) + " for search key/data: " + sequenceKey + "=>" + messageBytes); }

retVal = cursor.getNext(sequenceKey, messageBytes, LockMode.DEFAULT);
sequenceNumber = (Integer) sequenceBinding.entryToObject(sequenceKey);
}
}
...
}



 Comments   
Comment by James Olsen [ 26/Aug/10 ]

For clarity, the changed lines are:

while (retVal == OperationStatus.SUCCESS && sequenceNumber.intValue() <= endSequence) {
...
}
retVal = cursor.getNext(sequenceKey, messageBytes, LockMode.DEFAULT);

Generated at Tue May 14 08:13:12 UTC 2024 using JIRA 7.5.2#75007-sha1:9f5725bb824792b3230a5d8716f0c13e296a3cae.