if (metadataStubExt == null) {
throw new IllegalArgumentException("Metadata stub cannot be null");
}
AsyncResult asyncResult = result.getAsyncResult();
long timeSoFarMillis = getTimeSoFarInitMillis();
long pollingInternal = getInitialPollingInterval();
int applyMultipleAtCycle = getApplyMultipleRound();
int maxPollingTime = metadataStubExt.getReadTimeout();
if (logger.isDebugEnabled()) {
logger.debug("Start polling for response " + Calendar.getInstance().getTime().toString());
logger.debug("Initial polling interval will be " + pollingInternal + " milliseconds for "
+ applyMultipleAtCycle + " rounds");
logger.debug("Metadata API timeout set to " + Utils.timeoutToSecs(metadataStubExt.getReadTimeout()));
}
for (int i = 0;; i++) {
if (logger.isDebugEnabled()) {
logger.debug("");
logger.debug("#### Polling cycle round " + (i + 1) + " ####");
}
monitorSubTask(monitor, result.retrieveRealTimeStatusUpdatesIfAny());
// poll until it's done:
result.checkStatus();
if (logger.isDebugEnabled()) {
result.logStatus(logger);
}
if (result.isDone()) {
if (logger.isDebugEnabled()) {
addToCumulative(operationStats, timeSoFarMillis);
result.logResult(logger, operationStats);
}
// failed
if (result.isFailure()) {
String failureString = result.logFailure(logger);
if (logger.isDebugEnabled()) {
logger.debug("Polling failed after " + (timeSoFarMillis / 1000) + " secs for id '"
+ asyncResult.getId() + "'");
}
throw new ServiceException(failureString, result.getAsyncResult());
}
if (logger.isDebugEnabled()) {
logger.debug("Polling complete for operation id '" + asyncResult.getId() + "' after "
+ (timeSoFarMillis / 1000) + " secs");
}
// success
break;
}
try {
if (logger.isDebugEnabled()) {
logger.debug("Next poll will be in ~" + (double) pollingInternal / 1000 + " secs");
}
Thread.sleep(pollingInternal);
} catch (InterruptedException e) {} finally {
timeSoFarMillis += pollingInternal;
}
// record polling time to this point and evaluate base on limit
if (timeSoFarMillis > getMaxPollingTime()) {
logger.warn("Polling aborted after " + (timeSoFarMillis / 1000) + " secs for id '"
+ asyncResult.getId() + "'");
if (logger.isDebugEnabled()) {
addToCumulative(operationStats, timeSoFarMillis);
}
throw new ServiceTimeoutException("Server processing time has exceeded limit ("
+ Utils.timeoutToSecs(getMaxPollingTime()) + ")", metadataStubExt, result.getAsyncResult(),
operationStats);
}
// determine if polling multiple is to be applied
if (pollingInternal < maxPollingTime && i == (applyMultipleAtCycle - 1)) {
pollingInternal = pollingInternal * getPollingMultiple();
applyMultipleAtCycle += getApplyMultipleRound();
if (logger.isDebugEnabled()) {
logger.debug("Adjusted polling multiple, next application will be after round "
+ applyMultipleAtCycle);
}
}
try {
monitorCheck(monitor);
} catch (InterruptedException e) {
logger.warn("Polling canceled by user after " + (timeSoFarMillis / 1000) + " secs for id '"
+ asyncResult.getId() + "'");
throw e;
}
}
return result;