in evcache-core/src/main/java/com/netflix/evcache/operation/EVCacheLatchImpl.java [202:255]
public void onComplete(OperationFuture<?> future) throws Exception {
if (log.isDebugEnabled()) log.debug("BEGIN : onComplete - Calling Countdown. Completed Future = " + future + "; App : " + appName);
countDown();
completeCount++;
if(evcacheEvent != null) {
if (log.isDebugEnabled()) log.debug(";App : " + evcacheEvent.getAppName() + "; Call : " + evcacheEvent.getCall() + "; Keys : " + evcacheEvent.getEVCacheKeys() + "; completeCount : " + completeCount + "; totalFutureCount : " + totalFutureCount +"; failureCount : " + failureCount);
try {
if(future.isDone() && future.get().equals(Boolean.FALSE)) {
failureCount++;
if(failReason == null) failReason = EVCacheMetricsFactory.getInstance().getStatusCode(future.getStatus().getStatusCode());
}
} catch (Exception e) {
failureCount++;
if(failReason == null) failReason = IpcStatus.unexpected_error.name();
if(log.isDebugEnabled()) log.debug(e.getMessage(), e);
}
if(!onCompleteDone && getCompletedCount() >= getExpectedSuccessCount()) {
if(evcacheEvent.getClients().size() > 0) {
for(EVCacheClient client : evcacheEvent.getClients()) {
final List<EVCacheEventListener> evcacheEventListenerList = client.getPool().getEVCacheClientPoolManager().getEVCacheEventListeners();
for (EVCacheEventListener evcacheEventListener : evcacheEventListenerList) {
evcacheEventListener.onComplete(evcacheEvent);
}
onCompleteDone = true;//This ensures we fire onComplete only once
break;
}
}
}
if(scheduledFuture != null) {
final boolean futureCancelled = scheduledFuture.isCancelled();
if (log.isDebugEnabled()) log.debug("App : " + evcacheEvent.getAppName() + "; Call : " + evcacheEvent.getCall() + "; Keys : " + evcacheEvent.getEVCacheKeys() + "; completeCount : " + completeCount + "; totalFutureCount : " + totalFutureCount +"; failureCount : " + failureCount + "; futureCancelled : " + futureCancelled);
if(onCompleteDone && !futureCancelled) {
if(completeCount == totalFutureCount && failureCount == 0) { // all futures are completed
final boolean status = scheduledFuture.cancel(true);
run();//TODO: should we reschedule this method to run as part of EVCacheScheduledExecutor instead of running on the callback thread
if (log.isDebugEnabled()) log.debug("Cancelled the scheduled task : " + status);
}
}
}
if (log.isDebugEnabled()) log.debug("App : " + evcacheEvent.getAppName() + "; Call : " + evcacheEvent.getCall() + "; Keys : " + evcacheEvent.getEVCacheKeys() + "; completeCount : " + completeCount + "; totalFutureCount : " + totalFutureCount +"; failureCount : " + failureCount);
}
if(totalFutureCount == completeCount) {
final List<Tag> tags = new ArrayList<Tag>(5);
EVCacheMetricsFactory.getInstance().addAppNameTags(tags, appName);
if(evcacheEvent != null) tags.add(new BasicTag(EVCacheMetricsFactory.CALL_TAG, evcacheEvent.getCall().name()));
tags.add(new BasicTag(EVCacheMetricsFactory.FAIL_COUNT, String.valueOf(failureCount)));
tags.add(new BasicTag(EVCacheMetricsFactory.COMPLETE_COUNT, String.valueOf(completeCount)));
if(failReason != null) tags.add(new BasicTag(EVCacheMetricsFactory.IPC_STATUS, failReason));
//tags.add(new BasicTag(EVCacheMetricsFactory.OPERATION, EVCacheMetricsFactory.CALLBACK));
EVCacheMetricsFactory.getInstance().getPercentileTimer(EVCacheMetricsFactory.INTERNAL_LATCH, tags, Duration.ofMillis(EVCacheConfig.getInstance().getPropertyRepository().get(getAppName() + ".max.write.duration.metric", Integer.class)
.orElseGet("evcache.max.write.duration.metric").orElse(50).get().intValue())).record(System.currentTimeMillis()- start, TimeUnit.MILLISECONDS);
}
if (log.isDebugEnabled()) log.debug("END : onComplete - Calling Countdown. Completed Future = " + future + "; App : " + appName);
}