Details

      Description

      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:

      // a function for creating ListenableFuture from suspending lambda
      fun <T> listenableFuture(context: CoroutineContext = CommonPool, block: suspend () -> T): ListenableFuture<T>
       
      // a function for creating ListenableFuture from Deferred
      fun <T> Deferred<T>.asListenableFuture(): ListenableFuture<T>
       
      // an extension suspending function which awaits for ListenableFuture completion
      suspend fun <T> ListenableFuture<T>.await(): T
      

        Activity

        Hide
        konrad-kaminski Konrad Kamiński added a comment -

        I created a pull request.

        Show
        konrad-kaminski Konrad Kamiński added a comment - I created a pull request .
        Hide
        sdeleuze Sébastien Deleuze added a comment -

        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?

        Show
        sdeleuze Sébastien Deleuze added a comment - 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?
        Hide
        sdeleuze Sébastien Deleuze added a comment -

        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.

        Show
        sdeleuze Sébastien Deleuze added a comment - 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.
        Hide
        konrad-kaminski Konrad Kamiński added a comment -

        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:
        1. Create a parallel interface/implementation to the existing one, e.g. there 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.
        2. For every method which returns a Mono<T> provide instead a suspending function, which returns a T?.
        3. For every method which returns a 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.

        Show
        konrad-kaminski Konrad Kamiński added a comment - 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: 1. Create a parallel interface/implementation to the existing one, e.g. there 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. 2. For every method which returns a Mono<T> provide instead a suspending function , which returns a T? . 3. For every method which returns a 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.
        Hide
        sdeleuze Sébastien Deleuze added a comment -

        That's super useful Konrad Kamiński thank you! I will have a deeper look to this branch and send you my feedback.

        Show
        sdeleuze Sébastien Deleuze added a comment - That's super useful Konrad Kamiński thank you! I will have a deeper look to this branch and send you my feedback.

          People

          • Assignee:
            sdeleuze Sébastien Deleuze
            Reporter:
            konrad-kaminski Konrad Kamiński
            Last updater:
            Sébastien Deleuze
          • Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Days since last comment:
              13 weeks, 3 days ago