Which CoroutineScope to use for Spring Boot WebFlux endpoint





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















In a Spring Boot WebFlux application we have a number of endpoints (REST and GraphQL) which return a Mono or Flux of something. The code that these endpoints call is all non-blocking, but rather than using reactor we'd like to write all this non-blocking code using Kotlin coroutines. We can use a method such as kotlinx.coroutines.reactor.mono() to wrap our coroutines in a Mono (and the corresponding flux() method for Flux results).



In order to call these methods, though, we first need a CoroutineScope to wrap the whole request (and to handle things like cancelling any child coroutines which our main "entry point" coroutine starts). There seem to be several options here. For example, we could construct a new CoroutineScope and choose a dispatcher, e.g. CoroutineScope(Dispatchers.Default).mono {.... Or we could construct our own class which represents the whole HTTP request, and have that implement CoroutineScope, as shown here for an Android Activity.



Implicit within this question is the choice of what thread (or thread pool) the work should be executed on. We could create a thread pool ourselves, but Spring Boot WebFlux has already created its own thread pool for handling HTTP requests in a non-blocking environment, so maybe it's better to try to stay in the current thread (or in that thread pool)? If that is the best way to go, is there a way to get at that thread pool and get the coroutine to run on that?










share|improve this question































    1















    In a Spring Boot WebFlux application we have a number of endpoints (REST and GraphQL) which return a Mono or Flux of something. The code that these endpoints call is all non-blocking, but rather than using reactor we'd like to write all this non-blocking code using Kotlin coroutines. We can use a method such as kotlinx.coroutines.reactor.mono() to wrap our coroutines in a Mono (and the corresponding flux() method for Flux results).



    In order to call these methods, though, we first need a CoroutineScope to wrap the whole request (and to handle things like cancelling any child coroutines which our main "entry point" coroutine starts). There seem to be several options here. For example, we could construct a new CoroutineScope and choose a dispatcher, e.g. CoroutineScope(Dispatchers.Default).mono {.... Or we could construct our own class which represents the whole HTTP request, and have that implement CoroutineScope, as shown here for an Android Activity.



    Implicit within this question is the choice of what thread (or thread pool) the work should be executed on. We could create a thread pool ourselves, but Spring Boot WebFlux has already created its own thread pool for handling HTTP requests in a non-blocking environment, so maybe it's better to try to stay in the current thread (or in that thread pool)? If that is the best way to go, is there a way to get at that thread pool and get the coroutine to run on that?










    share|improve this question



























      1












      1








      1


      2






      In a Spring Boot WebFlux application we have a number of endpoints (REST and GraphQL) which return a Mono or Flux of something. The code that these endpoints call is all non-blocking, but rather than using reactor we'd like to write all this non-blocking code using Kotlin coroutines. We can use a method such as kotlinx.coroutines.reactor.mono() to wrap our coroutines in a Mono (and the corresponding flux() method for Flux results).



      In order to call these methods, though, we first need a CoroutineScope to wrap the whole request (and to handle things like cancelling any child coroutines which our main "entry point" coroutine starts). There seem to be several options here. For example, we could construct a new CoroutineScope and choose a dispatcher, e.g. CoroutineScope(Dispatchers.Default).mono {.... Or we could construct our own class which represents the whole HTTP request, and have that implement CoroutineScope, as shown here for an Android Activity.



      Implicit within this question is the choice of what thread (or thread pool) the work should be executed on. We could create a thread pool ourselves, but Spring Boot WebFlux has already created its own thread pool for handling HTTP requests in a non-blocking environment, so maybe it's better to try to stay in the current thread (or in that thread pool)? If that is the best way to go, is there a way to get at that thread pool and get the coroutine to run on that?










      share|improve this question
















      In a Spring Boot WebFlux application we have a number of endpoints (REST and GraphQL) which return a Mono or Flux of something. The code that these endpoints call is all non-blocking, but rather than using reactor we'd like to write all this non-blocking code using Kotlin coroutines. We can use a method such as kotlinx.coroutines.reactor.mono() to wrap our coroutines in a Mono (and the corresponding flux() method for Flux results).



      In order to call these methods, though, we first need a CoroutineScope to wrap the whole request (and to handle things like cancelling any child coroutines which our main "entry point" coroutine starts). There seem to be several options here. For example, we could construct a new CoroutineScope and choose a dispatcher, e.g. CoroutineScope(Dispatchers.Default).mono {.... Or we could construct our own class which represents the whole HTTP request, and have that implement CoroutineScope, as shown here for an Android Activity.



      Implicit within this question is the choice of what thread (or thread pool) the work should be executed on. We could create a thread pool ourselves, but Spring Boot WebFlux has already created its own thread pool for handling HTTP requests in a non-blocking environment, so maybe it's better to try to stay in the current thread (or in that thread pool)? If that is the best way to go, is there a way to get at that thread pool and get the coroutine to run on that?







      spring-boot kotlin spring-webflux project-reactor kotlinx.coroutines






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 23 '18 at 13:39









      Brian Clozel

      32.4k780106




      32.4k780106










      asked Nov 23 '18 at 9:40









      Yoni GibbsYoni Gibbs

      1,563115




      1,563115
























          1 Answer
          1






          active

          oldest

          votes


















          2














          Since in Spring WebFlux, HTTP exchanges are not tide to a specific thread, GlobalScope.mono(Dispatchers.Unconfined) is probably the best option.



          Notice that Dispatchers.Unconfined is an experimental API, as well as Coroutines channel API that will be deeply impacted by lazy iterable streams. So I would advise you to wait Spring official support for Coroutines for any production code.






          share|improve this answer
























          • Thanks for the reply. It says here that "Application code usually should use application-defined CoroutineScope, using async or launch on the instance of GlobalScope is highly discouraged." Is there an explanation for why in this case it's OK to use GlobalScope? (I know we're not using async or launch, but I thought the warning about GlobalScope applied in general.)

            – Yoni Gibbs
            Nov 23 '18 at 18:53








          • 1





            Indeed, since GlobalScope should be used very carefully at framework level, that's why I strongly advise to wait the official support we are working on. I think we will end up with a CoroutineScope that will be used at HTTP exchange level, with all the error, lifecycle listeners wired correctly.

            – Sébastien Deleuze
            Dec 4 '18 at 9:48












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53444069%2fwhich-coroutinescope-to-use-for-spring-boot-webflux-endpoint%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          Since in Spring WebFlux, HTTP exchanges are not tide to a specific thread, GlobalScope.mono(Dispatchers.Unconfined) is probably the best option.



          Notice that Dispatchers.Unconfined is an experimental API, as well as Coroutines channel API that will be deeply impacted by lazy iterable streams. So I would advise you to wait Spring official support for Coroutines for any production code.






          share|improve this answer
























          • Thanks for the reply. It says here that "Application code usually should use application-defined CoroutineScope, using async or launch on the instance of GlobalScope is highly discouraged." Is there an explanation for why in this case it's OK to use GlobalScope? (I know we're not using async or launch, but I thought the warning about GlobalScope applied in general.)

            – Yoni Gibbs
            Nov 23 '18 at 18:53








          • 1





            Indeed, since GlobalScope should be used very carefully at framework level, that's why I strongly advise to wait the official support we are working on. I think we will end up with a CoroutineScope that will be used at HTTP exchange level, with all the error, lifecycle listeners wired correctly.

            – Sébastien Deleuze
            Dec 4 '18 at 9:48
















          2














          Since in Spring WebFlux, HTTP exchanges are not tide to a specific thread, GlobalScope.mono(Dispatchers.Unconfined) is probably the best option.



          Notice that Dispatchers.Unconfined is an experimental API, as well as Coroutines channel API that will be deeply impacted by lazy iterable streams. So I would advise you to wait Spring official support for Coroutines for any production code.






          share|improve this answer
























          • Thanks for the reply. It says here that "Application code usually should use application-defined CoroutineScope, using async or launch on the instance of GlobalScope is highly discouraged." Is there an explanation for why in this case it's OK to use GlobalScope? (I know we're not using async or launch, but I thought the warning about GlobalScope applied in general.)

            – Yoni Gibbs
            Nov 23 '18 at 18:53








          • 1





            Indeed, since GlobalScope should be used very carefully at framework level, that's why I strongly advise to wait the official support we are working on. I think we will end up with a CoroutineScope that will be used at HTTP exchange level, with all the error, lifecycle listeners wired correctly.

            – Sébastien Deleuze
            Dec 4 '18 at 9:48














          2












          2








          2







          Since in Spring WebFlux, HTTP exchanges are not tide to a specific thread, GlobalScope.mono(Dispatchers.Unconfined) is probably the best option.



          Notice that Dispatchers.Unconfined is an experimental API, as well as Coroutines channel API that will be deeply impacted by lazy iterable streams. So I would advise you to wait Spring official support for Coroutines for any production code.






          share|improve this answer













          Since in Spring WebFlux, HTTP exchanges are not tide to a specific thread, GlobalScope.mono(Dispatchers.Unconfined) is probably the best option.



          Notice that Dispatchers.Unconfined is an experimental API, as well as Coroutines channel API that will be deeply impacted by lazy iterable streams. So I would advise you to wait Spring official support for Coroutines for any production code.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 23 '18 at 18:32









          Sébastien DeleuzeSébastien Deleuze

          3,1921626




          3,1921626













          • Thanks for the reply. It says here that "Application code usually should use application-defined CoroutineScope, using async or launch on the instance of GlobalScope is highly discouraged." Is there an explanation for why in this case it's OK to use GlobalScope? (I know we're not using async or launch, but I thought the warning about GlobalScope applied in general.)

            – Yoni Gibbs
            Nov 23 '18 at 18:53








          • 1





            Indeed, since GlobalScope should be used very carefully at framework level, that's why I strongly advise to wait the official support we are working on. I think we will end up with a CoroutineScope that will be used at HTTP exchange level, with all the error, lifecycle listeners wired correctly.

            – Sébastien Deleuze
            Dec 4 '18 at 9:48



















          • Thanks for the reply. It says here that "Application code usually should use application-defined CoroutineScope, using async or launch on the instance of GlobalScope is highly discouraged." Is there an explanation for why in this case it's OK to use GlobalScope? (I know we're not using async or launch, but I thought the warning about GlobalScope applied in general.)

            – Yoni Gibbs
            Nov 23 '18 at 18:53








          • 1





            Indeed, since GlobalScope should be used very carefully at framework level, that's why I strongly advise to wait the official support we are working on. I think we will end up with a CoroutineScope that will be used at HTTP exchange level, with all the error, lifecycle listeners wired correctly.

            – Sébastien Deleuze
            Dec 4 '18 at 9:48

















          Thanks for the reply. It says here that "Application code usually should use application-defined CoroutineScope, using async or launch on the instance of GlobalScope is highly discouraged." Is there an explanation for why in this case it's OK to use GlobalScope? (I know we're not using async or launch, but I thought the warning about GlobalScope applied in general.)

          – Yoni Gibbs
          Nov 23 '18 at 18:53







          Thanks for the reply. It says here that "Application code usually should use application-defined CoroutineScope, using async or launch on the instance of GlobalScope is highly discouraged." Is there an explanation for why in this case it's OK to use GlobalScope? (I know we're not using async or launch, but I thought the warning about GlobalScope applied in general.)

          – Yoni Gibbs
          Nov 23 '18 at 18:53






          1




          1





          Indeed, since GlobalScope should be used very carefully at framework level, that's why I strongly advise to wait the official support we are working on. I think we will end up with a CoroutineScope that will be used at HTTP exchange level, with all the error, lifecycle listeners wired correctly.

          – Sébastien Deleuze
          Dec 4 '18 at 9:48





          Indeed, since GlobalScope should be used very carefully at framework level, that's why I strongly advise to wait the official support we are working on. I think we will end up with a CoroutineScope that will be used at HTTP exchange level, with all the error, lifecycle listeners wired correctly.

          – Sébastien Deleuze
          Dec 4 '18 at 9:48




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53444069%2fwhich-coroutinescope-to-use-for-spring-boot-webflux-endpoint%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Paul Cézanne

          UIScrollView CustomStickyHeader Resize height generates problems when scroll is too fast

          Angular material date-picker (MatDatepicker) auto completes the date on focus out