in evcache-core/src/main/java/com/netflix/evcache/operation/EVCacheOperationFuture.java [264:313]
private static<T> CompletableFuture<Void> getNext(CompletableFuture<T> future,
final int j,
long timeout,
long splitTimeout,
TimeUnit unit,
int timeoutSlots) {
CompletableFuture<Void> next = new CompletableFuture<>();
if (future.isDone()) {
next.complete(null);
} else {
ScheduledFuture<?> scheduledTimeout;
if (j < timeoutSlots - 1) {
scheduledTimeout =
LazySharedExecutor.executor.schedule(
() -> {
if(log.isDebugEnabled()) log.debug("Completing now for loop {} and timeout slot {}", j, timeoutSlots);
next.complete(null);
},
splitTimeout,
TimeUnit.MILLISECONDS);
} else {
scheduledTimeout =
LazySharedExecutor.executor.schedule(
() -> {
next.complete(null);
if (future.isDone()) {
return;
}
if(log.isDebugEnabled()) log.warn("Throwing timeout exception after {} {} with timeout slot {}",
timeout,
unit,
timeoutSlots);
future.completeExceptionally(new TimeoutException("Timeout after " + timeout));
},
splitTimeout,
unit);
}
// If the completable future completes normally, don't bother timing it out.
// Also cleans the ref for GC.
future.whenComplete(
(r, exp) -> {
if (exp == null) {
scheduledTimeout.cancel(false);
if(log.isDebugEnabled()) log.debug("completing the future");
next.complete(null);
}
});
}
return next;
}