Description
Describe the bug
I tried to add a Redis cache by leveraging the new ValueCache
feature. On cache misses, my get
method would always return an exceptionally complete future. I noticed that everything is working as expected when batch loading is disabled. However, if I enabled batching, the batch function wouldn't always be triggered to fetch the data from the backend sources.
I see that in DataLoaderHelper, we would add the futures to a loader queue on cache misses when batching is enabled. Is it possible that the dispatch has already been called before the future is added to the queue? We don't manually make a dispatch call on the data loader. We just define a DataLoaderRegistry and pass it to the graphql-java engine in our codes. The batch mode is working fine if we only set the cache map and max batch size in the data loader options, but not if we also set a new value cache.
To Reproduce
Version: 3.0.1
I could reproduce the issue if I added a 3 seconds delay before calling future.completeExceptionally(exception)
, e.g.:
public CompletableFuture<V> get(K key) {
...
CompletableFuture<V> future = new CompletableFuture<>();
redisGetFuture.onComplete((value, exception) -> {
delay();
if (exception == null) {
if (value == null) {
future.completeExceptionally(new RuntimeException("null value"));
}
future.complete(value);
} else {
future.completeExceptionally(exception);
}
}
return future;
}
private void delay() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
}
}