long startSequenceNumber = clientSequenceNumber;
int notFoundCount = 0;
NotificationResult result = null;
long firstEarliest = -1;
while (result == null && !shouldStop()) {
NotificationResult nr;
try {
// 0 notifs to update startSequenceNumber
nr = cnf.fetchNotifs(startSequenceNumber, 0, 0L);
} catch (ClassNotFoundException e) {
logger.warning("NotifFetcher.fetchOneNotif",
"Impossible exception: " + e);
logger.debug("NotifFetcher.fetchOneNotif",e);
return null;
} catch (IOException e) {
if (!shouldStop())
logger.trace("NotifFetcher.fetchOneNotif", e);
return null;
}
if (shouldStop())
return null;
startSequenceNumber = nr.getNextSequenceNumber();
if (firstEarliest < 0)
firstEarliest = nr.getEarliestSequenceNumber();
try {
// 1 notif to skip possible missing class
result = cnf.fetchNotifs(startSequenceNumber, 1, 0L);
} catch (ClassNotFoundException | NotSerializableException | UnmarshalException e) {
logger.warning("NotifFetcher.fetchOneNotif",
"Failed to deserialize a notification: "+e.toString());
if (logger.traceOn()) {
logger.trace("NotifFetcher.fetchOneNotif",
"Failed to deserialize a notification.", e);
}
notFoundCount++;
startSequenceNumber++;
} catch (Exception e) {
if (!shouldStop())
logger.trace("NotifFetcher.fetchOneNotif", e);
return null;
}
}
if (notFoundCount > 0) {
final String msg =
"Dropped " + notFoundCount + " notification" +
(notFoundCount == 1 ? "" : "s") +
" because classes were missing locally or incompatible";
lostNotifs(msg, notFoundCount);
// Even if result.getEarliestSequenceNumber() is now greater than
// it was initially, meaning some notifs have been dropped
// from the buffer, we don't want the caller to see that
// because it is then likely to renotify about the lost notifs.
// So we put back the first value of earliestSequenceNumber
// that we saw.
if (result != null) {
result = new NotificationResult(
firstEarliest, result.getNextSequenceNumber(),
result.getTargetedNotifications());
}
}