Closed zche-theScore closed 3 weeks ago
/cc @Ladicek (redis), @cescoffier (redis), @gwenneg (cache), @machi1990 (redis)
I've been looking at this today and while I didn't conclude yet, I found one interesting thing: there's only one Vert.x worker thread in the pool. That thread waits for loading the value, which should also happen on the worker thread pool.
I tried setting quarkus.thread-pool.core-threads=8
, but that creates 8 different threads that are not used as Vert.x worker threads, so maybe there's an issue there. Not yet sure what.
OK, so when I run the app in the prod mode, where the Vert.x worker thread pool and the Quarkus thread pool indeed are identical, it still doesn't work.
Then, I tried replacing the GraphQL resolver with a JAX-RS resource and it works just fine. That suggests that SmallRye GraphQL's execution model is perhaps somewhat different than RESTEasy Reactive's.
I looked further and found that the problem might be in that the Redis cache implementation uses an ordered worker submission. That is, it requests that both actions are executed on the same worker thread. Not sure why that works fine with JAX-RS and doesn't work with GraphQL...
OK, so I have figured out a workaround -- configure
quarkus.smallrye-graphql.nonblocking.enabled=false
Why does that make it work? The method is clearly blocking, so what's the difference?
The difference is that with quarkus.smallrye-graphql.nonblocking.enabled=false
, the GraphQL route is registered as blocking, which essentially boils down to BlockingHandlerDecorator
, which is created with the ordered
parameter set to false
. On the other hand, in the default configuration, the GraphQL route is registered as non-blocking and the blocking is done in BlockingHelper.runBlocking
, which doesn't pass the ordered
parameter, which is equivalent to passing true
.
It seems to me that this should pass false
explicitly -- then it works.
Describe the bug
When I tried to use Redis Cache
@CacheResult()
in a GraphQL resolver which runs in a worker thread, it hangs and gives and errorThere's no problem if I switch the GraphQL resolver to using
Uni
which makes it run in a event-loop thread. There's no problem if I used Caffeine Cache. There's no problem if there exists the cache entry in Redis.Reproducer: https://github.com/zche-theScore/quarkus-redis-cache-blocking
Expected behavior
I didn't see any note saying Redis Cache can only be used on event-loop thread in the docs.
Actual behavior
Redis Cache
@CacheResult()
makes a worker thread hang.How to Reproduce?
Reproducer: https://github.com/zche-theScore/quarkus-redis-cache-blocking
Output of
uname -a
orver
Darwin ca-on-a-zche.local 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000 arm64
Output of
java -version
openjdk 22.0.1 2024-04-16 OpenJDK Runtime Environment (build 22.0.1+8-16) OpenJDK 64-Bit Server VM (build 22.0.1+8-16, mixed mode, sharing)
Quarkus version or git rev
3.13.0
Build tool (ie. output of
mvnw --version
orgradlew --version
)Apache Maven 3.9.8 (36645f6c9b5079805ea5009217e36f2cffd34256)
Additional information
No response