AxonFramework / extension-kotlin

Axon Framework extension for Kotlin integration to ease development in Kotlin.
https://axoniq.io/
Apache License 2.0
43 stars 9 forks source link

`@EventHandler` does not support kotlin coroutine #20

Open UkonnRa opened 4 years ago

UkonnRa commented 4 years ago

Axon version

4.3

Example

    @EventHandler
    suspend fun on(event: UserEvent.Updated) {
        userRepository.update(event)
    }

Result

Caused by: org.axonframework.messaging.annotation.UnsupportedHandlerException: Unable to resolve parameter 1 (Continuation) in handler public java.lang.Object com.ukonnra.wonderland.teaparty.application.service.UserProjection.on(com.ukonnr
a.wonderland.teaparty.domain.user.UserEvent$Updated,kotlin.coroutines.Continuation<? super kotlin.Unit>).
smcvb commented 4 years ago

So, I am assuming the request you are having is to provide support for coroutine function in Kotlin, correct @UkonnRa? Although the statement is clear, speaking out the desired approach would be beneficial too. No worries for now by the way, just for future reference.

At the moment, I am not a 100% sure whether this would be a Kotlin-Extension issue only, as this imposes some requirements from event handling function for anybody.

Due to the unclarity at this stage, I have marked the issue as "Under Discussion". Added, the priority is "Could" for the time being. As soon as we start taking off on it, we will make sure to update the ticket accordingly.

UkonnRa commented 4 years ago

Well, now axon does support the return type CompletableFuture<T> in Java, so I wonder if Reactor, RxJava and Kotlin Coroutine will be supported also

smcvb commented 4 years ago

I can ascertain you we are looking into those options as well. :-)

We need to find the right place and time for this first though, of course.

jnfeinstein commented 4 years ago

@smcvb what is the state of coroutine support within the Axon Framework? I don't think I can use suspend fun directly as a handler per the described issue, but will using GlobalScope.launch to launch a coroutine work in harmony with the aggregate / saga / UnitOfWork? Does a coroutine need to be called using runBlocking?

smcvb commented 4 years ago

@jnfeinstein at the moment this issue does not have any major priority given all the other topics we are working on.

Additionally, I don't have any personal experience with trying out coroutines within Aggregates, Sagas, etc, thus would be unable to share any info on this.

Maybe @sandjelkovic has performed some trails on the matter?

jnfeinstein commented 4 years ago

Well, multi-threaded or asynchronous calls in general, coroutine or not.

sandjelkovic commented 4 years ago

For coroutines, @jnfeinstein you are correct that you have to run them inside a runBlocking block. Continuations are currently not supported.

Basically, once you return from your Event handler method, it is considered that the event has been handled. That is why you need to run and complete or cancel all your coroutines while inside your method block/expression.

gklijs commented 2 months ago

@UkonnRa and @jnfeinstein if still interested in a more elegant solution, you could give https://github.com/AxonFramework/extension-kotlin/tree/coroutines_module/kotlin-coroutine a try. It's not working with annotations yet, but that could be added. It does make the event handling async, and decoupled from updating the tracking tokens.