Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Retry not working with Kotlin Async Coroutine #303

Open
nayanseth opened this issue Jun 16, 2022 · 2 comments
Open

Spring Retry not working with Kotlin Async Coroutine #303

nayanseth opened this issue Jun 16, 2022 · 2 comments

Comments

@nayanseth
Copy link

Note: the below function test is being called via a launch coroutine.

The following code works:

@Retryable(value=[RetryException::class])
suspend fun test() {
  throw RetryException("blah")
}

However, the moment I add an async call, retry stops working:

@Retryable(value=[RetryException::class])
suspend fun test() {
  val deferred = supervisorScope {
    async { library.method() }
  }
  deferred.await()
  throw RetryException("blah")
}

What could be wrong?

@artembilan
Copy link
Member

The @Retryable creates a proxy call around the method with try...catch.
I don't think that Kotlin async behavior does fit into the try...catch model.

It might be great to see a generated Java code back from this Kotlin to determine when exactly that @Retryable sits in the call stack.
It is very likely that there are some anonymous classes are generated and their method calls are done in the separate thread which is already out of retry proxy.

@sdeleuze
Copy link

sdeleuze commented Jun 17, 2022

You can find more information on Coroutines exception handling here. Maybe worth to have a reproducer to analyze the behavior and evaluate if that makes sense to support it.

If not supported, maybe worth to throw an early error at startup if possible and document it is not supported, leveraging KotlinDetector.isSuspendingFunction() to avoid silent failures.

Not sure if that matters here, but from a bytecode / Java reflection perspective, suspend fun test() in Kotlin will be translated to something like Object test(Continuation continuation) in Java, so to get the real signature you need to identify suspending functions with KotlinDetector.isSuspendingFunction() and then for example use Kotlin reflection to get the real return value / parameter via ReflectJvmMapping.getKotlinFunction (see usages in Spring Framework). Also if you want to re-invoke the suspending function, you probably need to leverage Kotlin reflection API as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants