Open u6f6o opened 2 years ago
/cc @evanchooly, @gwenneg
A possible workaround for this issue is to wrap the cached method and to use the kotlin-mutiny lib:
@ApplicationScoped
class StationAmbassador(
@RestClient
private val stationConfigClient: StationConfigClient
) {
suspend fun stationConfig(stationId: String): StationConfig? {
return stationConfig().awaitSuspending()[stationId]
}
@CacheResult(cacheName = "station-config")
fun stationConfig(): Uni<Map<String, StationConfig>> {
return stationConfigClient
.loadStationConfig()
.onItem()
.transform { snapshot ->
Log.infof(
"Fetched {} stations (hd: {}, sd: {}, newTv: {}) from product-configuration.",
snapshot.stationsCount,
snapshot.hdStationsCount,
snapshot.sdStationsCount,
snapshot.newTvStationsCount
)
snapshot.stations.associateBy { it.id }
}
}
}
I'm not familiar enough with all this to create a reproducer on my own. Can you put one together and I'll dig in to it? Thanks.
Sure 👍 : https://github.com/u6f6o/quarkus-suspend-cache-issue If you run the test, it should fail with someting like:
Mar 14, 2022 6:27:56 PM io.quarkus.vertx.http.runtime.QuarkusErrorHandler handle
ERROR: HTTP Request to /hello failed, error id: 07c07c3e-4ed8-4a00-88e0-f90c9c69f60d-1
java.lang.IllegalStateException: The current thread cannot be blocked: vert.x-eventloop-thread-9 @coroutine#1
at io.smallrye.mutiny.operators.uni.UniBlockingAwait.await(UniBlockingAwait.java:30)
at io.smallrye.mutiny.groups.UniAwait.atMost(UniAwait.java:65)
at io.smallrye.mutiny.groups.UniAwait.indefinitely(UniAwait.java:46)
at io.quarkus.cache.runtime.CacheResultInterceptor.intercept(CacheResultInterceptor.java:115)
at io.quarkus.cache.runtime.CacheResultInterceptor_Bean.intercept(Unknown Source)
at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
at org.acme.GreetingService_Subclass.sayMyName(Unknown Source)
at org.acme.GreetingService_ClientProxy.sayMyName(Unknown Source)
at org.acme.GreetingResource.hello$suspendImpl(GreetingResource.kt:16)
at org.acme.GreetingResource.hello(GreetingResource.kt)
at org.acme.GreetingResource$quarkuscoroutineinvoker$hello_efb111fc5da56e7b2d25b0ef5b3b839c46bb2656.invokeCoroutine(Unknown Source)
at org.jboss.resteasy.reactive.server.runtime.kotlin.CoroutineInvocationHandler$handle$1.invokeSuspend(CoroutineInvocationHandler.kt:40)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at org.jboss.resteasy.reactive.server.runtime.kotlin.VertxDispatcher.dispatch$lambda-0(ApplicationCoroutineScope.kt:39)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:63)
at io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:38)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:829)
So I've poked at this a bit and i think the changes (more specifically where) that are likely needed needs someone a bit more familiar with the caching code. Perhaps @mkouba would know or know who to ping?
I can help with that @evanchooly.
Is someone working on this? If not, I can pick it up
Sorry, I'm swamped with other subjects, I couldn't find the time to look at this one so far. Feel free to pick it up @geoand.
@evanchooly have you started looking into this?
This issue and #21592 could be related.
I didn't get far. I'm out this week at a conference so please take it.
I doubt I'll have time this week, but if I do, I'll let you know
Any updates on this issue?
Nope, things have pilled up so this has moved to the back of my list
@geoand Any updates? Maybe for 2.13 😄 ?
Not a chance :)
Other things keep getting higher priority, so I really don't know when I'll get around to this
@geoand Is there any MR that I could use as a reference point? I was thinking about having a look and deciding whether I feel capable to create a MR on my own.
https://github.com/quarkusio/quarkus/pull/24741 is probably somewhat similar
Any progress on this?
Not yet
Any progress perhaps?:)
@Ladicek made recently great progress to simplify the support of kotlin coroutines support in Quarkus itself (https://github.com/quarkusio/quarkus/issues/26728#issuecomment-1993762397; https://github.com/quarkusio/quarkus/pull/40815). Maybe this info helps in implementing this feature.
Any update?
Describe the bug
Quarkus-cache does not work correctly with kotlin suspend functions. The following code snippet
results in
We can workaround this behaviour by returning a CompletionStage from the rest client and work with unis instead.
Expected behavior
Quarkus-cache should work with suspend functions as well.
Actual behavior
How to Reproduce?
No response
Output of
uname -a
orver
Darwin MB-07-P15.fritz.box 19.6.0 Darwin Kernel Version 19.6.0: Mon Aug 31 22:12:52 PDT 2020; root:xnu-6153.141.2~1/RELEASE_X86_64 x86_64
Output of
java -version
openjdk version "11.0.13" 2021-10-19 OpenJDK Runtime Environment GraalVM CE 20.3.4 (build 11.0.13+7-jvmci-20.3-b24) OpenJDK 64-Bit Server VM GraalVM CE 20.3.4 (build 11.0.13+7-jvmci-20.3-b24, mixed mode, sharing)
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.7.0.Final
Build tool (ie. output of
mvnw --version
orgradlew --version
)Gradle 7.3.3
Additional information
No response