int numAfterDone = 0;
int resetCount = 0;
// Keep trying until the rs is back up and we've gotten a put through
while (numAfterDone < maxIterations) {
long start = System.nanoTime();
TraceScope scope = null;
try {
scope = Trace.startSpan(getSpanName(), AlwaysSampler.INSTANCE);
boolean actionResult = doAction();
if (actionResult && future.isDone()) {
numAfterDone++;
}
// the following Exceptions derive from DoNotRetryIOException. They are considered
// fatal for the purpose of this test. If we see one of these, it means something is
// broken and needs investigation. This is not the case for all children of DNRIOE.
// Unfortunately, this is an explicit enumeration and will need periodically refreshed.
// See HBASE-9655 for further discussion.
} catch (AccessDeniedException e) {
throw e;
} catch (CoprocessorException e) {
throw e;
} catch (FatalConnectionException e) {
throw e;
} catch (InvalidFamilyOperationException e) {
throw e;
} catch (NamespaceExistException e) {
throw e;
} catch (NamespaceNotFoundException e) {
throw e;
} catch (NoSuchColumnFamilyException e) {
throw e;
} catch (TableExistsException e) {
throw e;
} catch (TableNotFoundException e) {
throw e;
} catch (RetriesExhaustedException e){
throw e;
// Everything else is potentially recoverable on the application side. For instance, a CM
// action kills the RS that hosted a scanner the client was using. Continued use of that
// scanner should be terminated, but a new scanner can be created and the read attempted
// again.
} catch (Exception e) {
resetCount++;
if (resetCount < maxIterations) {
LOG.info("Non-fatal exception while running " + this.toString()
+ ". Resetting loop counter", e);
numAfterDone = 0;
} else {
LOG.info("Too many unexpected Exceptions. Aborting.", e);
throw e;
}
} finally {
if (scope != null) {
scope.close();
}
}
result.addResult(System.nanoTime() - start, scope.getSpan());
}
return result;
}