-
Hi, I've problem with PF v2.9.x/v3.x + async caffeine cache + CompletableFuture.join() work together. The sample code:
public CompletionStage<Result> setCache() {
return cache.set(cacheKey, "2000").thenApply(done -> ok());
}
public Result test() {
String value = getValueFromCache()
.toCompletableFuture()
.join()
.orElse("no value");
System.out.println("value = " + value);
return ok(value);
}
public CompletionStage<Optional<String>> getValueFromCache() {
return cache.get(cacheKey);
} The problem is that getting value from cache, if set earlier, hangs "forever" (the println is never printed). I've tried this: https://www.playframework.com/documentation/2.9.x/JavaCache#Setting-the-execution-context but with no success: play.cache.dispatcher = "contexts.blockingCacheDispatcher"
contexts {
blockingCacheDispatcher {
fork-join-executor {
parallelism-factor = 3.0
}
}
} What's maybe can be also interesting that it works perfect with ehcache. Moreover, this code works: public CompletionStage<Result> testCs() {
return getValueFromCache().thenApply(valueFromCache -> {
String value = valueFromCache.orElse("no value");
System.out.println("value CS = " + value);
return ok("CS " + value);
});
} but my real problem is that I have quite big project already (from v2.8) and there is many .join() nested calls Is there any chance I can make the code works? This is some bug in PF/caffeine or I set something wrong or maybe .join() in PF does not work with caffeine anymore...? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
So yeah this worked with Play 2.8 but now your code deadlocks in Play 2.9 and 3.0... In your case, the call to So thinking about it, I am reluctant to revert this change, because, like said, it's meant to speed up things (and question would be which thread pool should we use? why should we revert the use of trampline here but not somewhere else? -> which makes me think that using Morever, looking at your code I would argue your use of Actually you already solved the problem yourself in You do have to refactor your code a bit and in general avoid blocking with calls to |
Beta Was this translation helpful? Give feedback.
-
Sorry for late response but thanks for answer. I've refactored code not to use .join() but .thenApply. |
Beta Was this translation helpful? Give feedback.
So yeah this worked with Play 2.8 but now your code deadlocks in Play 2.9 and 3.0...
The code change "causing" this is 6b17ee9#diff-039dc927703c7a9f8f525d7b6cef5b27ae98e93d5fb9489ec84464b731be00c2R222, where I switched the executioncontext of some very lightwight operation to be a Play internal
trampline
executor. Usingtrampoline
just means that the execution of a task should not happen on another thread (of maybe another thread pool) but the exact same thread that is already executing. The intention is to avoid thread switching for very lightwight things like casting, etc. (like the code referenced), to avoid unnecessary slowdowns. The thing is we do usetrampoline
not just in the cache…