Closed spring-projects-issues closed 5 years ago
Konrad Kamiński commented
I created a pull request.
Sébastien Deleuze commented
Thanks for contributing this pull request.
Kotlin coroutines seems indeed a good fit for ListenableFuture
, but since coroutines are still experimental, I prefer to wait before integrating such support in Spring Framework codebase.
I would suggest submitting a similar pull request on kotlinx.coroutines in order to provide such support like it has been done for Reactor Flux
and Mono
types. Any chance you could do that?
Sébastien Deleuze commented
Konrad Kamiński I turn this issue into a global coroutine support one, since there may be other areas than ListenableFuture
impacted as shown by your spring-kotlin-coroutine project.
Did you experiment with coroutines + Spring WebFlux? After reading the guide to reactive streams with coroutines, it seems to me this is something worth to explore if we can leverage the existing Reactor based infrastructure of Spring WebFlux (via annotation or functional API) to provide the ability to use imperative style code for those who are not confortable with functional APIs.
That said we really need to experiment in order to see how this work with backpressure, see if it can enable easily to implement custom operator as advertised, etc.
I am quite confident about the ListenableFuture
/ Mono
use case but the Flux
use case is less obvious to me.
Any sample WebFlux + coroutine application example could help to move this topic forward.
Konrad Kamiński commented
I created a proof-of-concept implementation of mixit application with coroutines. I have not yet touched either WebClient
or WebSocket
API. The basic approach to introducing coroutines with Spring WebFlux is:
CoroutineServerRequest
/DefaultCoroutineServerRequest
for ServerRequest
which on the one hand is a wrapper around the Reactor
based API and on the other provides a coroutines-based API.Mono<T>
provide instead a suspending function, which returns a T?
.Flux<T>
provide instead a suspending or regular function, which returns ReceivableChannel<T>
.In this poc I only covered whatever was needed for the mixit
application to work, though I may have missed something since I have not checked the application thoroughly. I left the tests untouched and they seem to work fine. :)
Sébastien Deleuze commented
That's super useful Konrad Kamiński thank you! I will have a deeper look to this branch and send you my feedback.
Sébastien Deleuze commented
I have submitted a pull-request on kotlinx.coroutines to upgrade Reactor coroutine support from Aluminium
to Bismuth
release train.
Sébastien Deleuze commented
Reactor Bismuth and Spring Framework 5 support is now available as part of kotlinx.coroutines 0.19.1.
Sébastien Deleuze commented
Konrad Kamiński Now that Spring Framework 5 and Reactor Core 3.1 are GA + are supported in kotlinx.coroutines
, do you have any plan to add WebFlux support to your great project https://github.com/konrad-kaminski/spring-kotlin-coroutine ? Based on what you did on MiXiT application, and now that our APIs are stable, I guess it could be useful for Spring + Kotlin developers to have CoroutineFoo
variants of the ReactiveFoo
main existing ones, + provide some extensions to have a bridge between the 2 worlds ? I would be interested to have your thoughts on this.
Sébastien Deleuze commented
Some additional thoughts about bridging Reactor-based APIs to Coroutines based on your previous experiment.
For streaming use case, Flux<T>
-> suspending function which returns ReceivableChannel<T>
should be fine. On that topic, it seems that channel operators are coming on Coroutine side.
For non streaming use cases, maybe most of the time translating Flux<T>
-> suspending function which returns List<T>
via a preliminary call to Flux.collectList()
will be more efficient and more familiar with the programming model people have in non-Reactive world and in line with the goal of Coroutines to provide a simplified imperative like programming model.
Mono<T>
could translate to suspending function which returns T
(most of the time) or T?
depending on the context (should be specified in the Javadoc, if not please raise an issue).
Mono<Void>
could translate to suspending function which returns Unit
.
Sébastien Deleuze commented
See this PR comment.
Sébastien Deleuze commented
A quick update:
Coroutines support for WebClient
and WebFlux.fn has been merged in master
branch via this commit which is the first part of a more complete Coroutines support coming in Spring Framework 5.2. It introduces suspendable Kotlin extensions for Mono
based methods in WebFlux classes like WebClient
, ServerRequest
, ServerResponse
as well as a Coroutines router usable via coRouter { }
. See more details in the Coroutines section of the reference documentation.
Coroutines extensions use await
prefix or AndAwait
suffix, and most are using names close to their Reactive counterparts, except exchange
in WebClient.RequestHeadersSpec
which translates to awaitResponse
.
Upcoming expected changes are:
Dispatchers.Unconfined
(Kotlin/kotlinx.coroutines#972)Flux
based API (Kotlin/kotlinx.coroutines#254)CoroutineContext
(Kotlin/kotlinx.coroutines#284)ReactiveAdapterRegistry
I am also preparing pull-requests for Spring Data MongoDB and Spring Data R2DBC.
A demo project is available in this spring-boot-coroutines-demo repository.
Support for WebFlux annotated controllers, including view resolution and Deferred
, has been merged in master
branch. See this sample Coroutines controller for a concrete example.
With Coroutines Flow
support (see this commit), Spring Framework Coroutines support is now complete. See https://github.com/sdeleuze/spring-boot-coroutines-demo for concrete examples of Flow
usage and also see :
Flow
documentationFlow
API is not frozen yetA detailed blog post is coming next week to present an overview of Spring Coroutines support.
Konrad Kamiński opened SPR-15413 and commented
Since
1.1
Kotlin supports coroutines. Its library support includes utility functions for converting suspending functions/lambdas to/from CompletableFuture / Deferred. It would be nice to have such support ListenableFuture as well.The API could look as follows:
Affects: 5.0 M5
Issue Links:
21058 Incorrect return type of Kotlin suspending functions
Referenced from: pull request https://github.com/spring-projects/spring-framework/pull/1375
18 votes, 26 watchers