Does GlobalScope.launch create a new thread or run in the same thread?In Kotlin, is it possible to change delegation at Runtime?Difference between thread and coroutine in KotlinIs there a context for corutines that creates new threads up to a limit like a ThreadPoolExecutor?Stop Thread in Kotlinkotlin coroutines - use main thread in run blockingwhy coroutines 1st run on caller thread but after first suspension point it runs on DefaultExecutor in “Dispatchers.Unconfined”?Basic coroutine network call in a libraryKotlin Coroutines - Different options for using Coroutine Scope/Context?Does Kotlin delay use a dispatcher internally to unblock the caller thread?Is delay() In Kotlin Coroutine a non-blocking function?

QR codes, do people use them?

Deck of Cards with Shuffle and Sort functionality

How to "add vert" in blender 2.8?

Category-theoretic treatment of diffs, patches and merging?

How do I talk to my wife about unrealistic expectations?

How can I review my manager, who is fine?

How many Jimmys can fit?

Where are the Wazirs?

Curly braces adjustment in tikz?

Is there a method for differentiating informative comments from commented out code?

Wires do not connect in Circuitikz

Is it okay to use open source code to do an interview task?

Four ships at the ocean with the same distance

Is "wissen" the only verb in German to have an irregular present tense?

Why does Trump want a citizenship question on the census?

What does "spinning upon the shoals" mean?

How do resistors generate different heat if we make the current fixed and changed the voltage and resistance? Notice the flow of charge is constant

What exactly is a "murder hobo"?

Is there a Redo (Undo Undo) function in Super Mario Maker 2?

Tikz, arrow formatting

What are the consequences for a developed nation to not accept any refugees?

Computer name naming convention for security

My professor has told me he will be the corresponding author. Will it hurt my future career?

What do you call a situation where you have choices but no good choice?



Does GlobalScope.launch create a new thread or run in the same thread?


In Kotlin, is it possible to change delegation at Runtime?Difference between thread and coroutine in KotlinIs there a context for corutines that creates new threads up to a limit like a ThreadPoolExecutor?Stop Thread in Kotlinkotlin coroutines - use main thread in run blockingwhy coroutines 1st run on caller thread but after first suspension point it runs on DefaultExecutor in “Dispatchers.Unconfined”?Basic coroutine network call in a libraryKotlin Coroutines - Different options for using Coroutine Scope/Context?Does Kotlin delay use a dispatcher internally to unblock the caller thread?Is delay() In Kotlin Coroutine a non-blocking function?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








1















I have the question from this code.



https://kotlinlang.org/docs/reference/coroutines/basics.html



fun main() 
GlobalScope.launch // launch new coroutine in background and continue
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay

println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive



I replace delay(1000L) with Thread.sleep(1000L). If GlobalScope.launch block will run in the same thread, the Thread.sleep(1000L) will block the thread. However it seems not.



fun main() 
GlobalScope.launch // launch new coroutine in background and continue
Thread.sleep(1000L)
println("World!")

println("Hello,") //
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive










share|improve this question






















  • Found it. In the 2 examples, GlobalScope.launch runs in a different thread.

    – user1443721
    Mar 26 at 5:41

















1















I have the question from this code.



https://kotlinlang.org/docs/reference/coroutines/basics.html



fun main() 
GlobalScope.launch // launch new coroutine in background and continue
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay

println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive



I replace delay(1000L) with Thread.sleep(1000L). If GlobalScope.launch block will run in the same thread, the Thread.sleep(1000L) will block the thread. However it seems not.



fun main() 
GlobalScope.launch // launch new coroutine in background and continue
Thread.sleep(1000L)
println("World!")

println("Hello,") //
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive










share|improve this question






















  • Found it. In the 2 examples, GlobalScope.launch runs in a different thread.

    – user1443721
    Mar 26 at 5:41













1












1








1








I have the question from this code.



https://kotlinlang.org/docs/reference/coroutines/basics.html



fun main() 
GlobalScope.launch // launch new coroutine in background and continue
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay

println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive



I replace delay(1000L) with Thread.sleep(1000L). If GlobalScope.launch block will run in the same thread, the Thread.sleep(1000L) will block the thread. However it seems not.



fun main() 
GlobalScope.launch // launch new coroutine in background and continue
Thread.sleep(1000L)
println("World!")

println("Hello,") //
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive










share|improve this question














I have the question from this code.



https://kotlinlang.org/docs/reference/coroutines/basics.html



fun main() 
GlobalScope.launch // launch new coroutine in background and continue
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay

println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive



I replace delay(1000L) with Thread.sleep(1000L). If GlobalScope.launch block will run in the same thread, the Thread.sleep(1000L) will block the thread. However it seems not.



fun main() 
GlobalScope.launch // launch new coroutine in background and continue
Thread.sleep(1000L)
println("World!")

println("Hello,") //
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive







kotlin kotlin-coroutines






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 25 at 22:27









user1443721user1443721

2191 gold badge5 silver badges19 bronze badges




2191 gold badge5 silver badges19 bronze badges












  • Found it. In the 2 examples, GlobalScope.launch runs in a different thread.

    – user1443721
    Mar 26 at 5:41

















  • Found it. In the 2 examples, GlobalScope.launch runs in a different thread.

    – user1443721
    Mar 26 at 5:41
















Found it. In the 2 examples, GlobalScope.launch runs in a different thread.

– user1443721
Mar 26 at 5:41





Found it. In the 2 examples, GlobalScope.launch runs in a different thread.

– user1443721
Mar 26 at 5:41












3 Answers
3






active

oldest

votes


















1














The GlobalScope lets you start coroutines which more-or-less have the same behavior as daemon threads since they are detached from any Coroutine-Job and basically run as long as the application. Their lifecycle is only limited by the application itself. This is something you want to avoid by using "structured concurrency" which basically means that your coroutines should be nested in a way that you can control them without manually keeping track of their references and joining them for example in order to await their computations. So in your real-life code you should avoid GlobalScope as much as possible, since there's most certainly a better solution.



As to your question, and as already mentioned, the GlobalScope runs on the Dispatchers.Default pool, which means that you will block some worker thread but not the one you spawned the coroutine from.



On the other hand, if you were to write this block:



fun main() 
runBlocking
Thread.sleep(1000L)
println("World!")

println("Hello,")
Thread.sleep(2000L)



you'll see that the coroutine blocks the main thread and the output will show a different result. That is because runBlocking runs on the caller thread main rather than one of the worker pool threads.






share|improve this answer






























    0














    The GlobalScope.launch.. function will not block. It returns an Job object, which you may use to wait for a result.



    Behind the scenes, the GlobalScope uses the default dispatcher Dispatchers.Default. You may see it, for example, by printing a thread name inside a launch.. function.



    You will need to run more coroutines to see them blocking each other because of Thread.sleep calls.



    https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html






    share|improve this answer






























      0














      GlobalScope.launch will not necessarily create a new thread, but it will use one from a shared pool because it uses the Default dispatcher. So, as far as your question is concerned, in your snippet, the block passed to launch runs in a different thread indeed.



      In the documentation about dispatchers and threads, you will find the following:




      The default dispatcher, that is used when coroutines are launched in GlobalScope, is represented by Dispatchers.Default and uses shared background pool of threads




      And in the Dispatchers.Default doc, you can find:




      By default, the maximal level of parallelism used by this dispatcher is equal to the number of CPU cores, but is at least two. Level of parallelism X guarantees that no more than X tasks can be executed in this dispatcher in parallel.




      Note that you could change the dispatcher by providing one as a parameter of launch.






      share|improve this answer

























      • "but it will use one from a shared pool". Do you imply GlobalScope.launch runs in another thread, if the CPU has at least 2 cores?

        – user1443721
        Mar 26 at 3:42











      • Not really. In fact, the pool contains at least 2 threads, even for single code processors. That what the doc states if I understood correctly.

        – Joffrey
        Mar 26 at 7:38













      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%2f55347302%2fdoes-globalscope-launch-create-a-new-thread-or-run-in-the-same-thread%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      The GlobalScope lets you start coroutines which more-or-less have the same behavior as daemon threads since they are detached from any Coroutine-Job and basically run as long as the application. Their lifecycle is only limited by the application itself. This is something you want to avoid by using "structured concurrency" which basically means that your coroutines should be nested in a way that you can control them without manually keeping track of their references and joining them for example in order to await their computations. So in your real-life code you should avoid GlobalScope as much as possible, since there's most certainly a better solution.



      As to your question, and as already mentioned, the GlobalScope runs on the Dispatchers.Default pool, which means that you will block some worker thread but not the one you spawned the coroutine from.



      On the other hand, if you were to write this block:



      fun main() 
      runBlocking
      Thread.sleep(1000L)
      println("World!")

      println("Hello,")
      Thread.sleep(2000L)



      you'll see that the coroutine blocks the main thread and the output will show a different result. That is because runBlocking runs on the caller thread main rather than one of the worker pool threads.






      share|improve this answer



























        1














        The GlobalScope lets you start coroutines which more-or-less have the same behavior as daemon threads since they are detached from any Coroutine-Job and basically run as long as the application. Their lifecycle is only limited by the application itself. This is something you want to avoid by using "structured concurrency" which basically means that your coroutines should be nested in a way that you can control them without manually keeping track of their references and joining them for example in order to await their computations. So in your real-life code you should avoid GlobalScope as much as possible, since there's most certainly a better solution.



        As to your question, and as already mentioned, the GlobalScope runs on the Dispatchers.Default pool, which means that you will block some worker thread but not the one you spawned the coroutine from.



        On the other hand, if you were to write this block:



        fun main() 
        runBlocking
        Thread.sleep(1000L)
        println("World!")

        println("Hello,")
        Thread.sleep(2000L)



        you'll see that the coroutine blocks the main thread and the output will show a different result. That is because runBlocking runs on the caller thread main rather than one of the worker pool threads.






        share|improve this answer

























          1












          1








          1







          The GlobalScope lets you start coroutines which more-or-less have the same behavior as daemon threads since they are detached from any Coroutine-Job and basically run as long as the application. Their lifecycle is only limited by the application itself. This is something you want to avoid by using "structured concurrency" which basically means that your coroutines should be nested in a way that you can control them without manually keeping track of their references and joining them for example in order to await their computations. So in your real-life code you should avoid GlobalScope as much as possible, since there's most certainly a better solution.



          As to your question, and as already mentioned, the GlobalScope runs on the Dispatchers.Default pool, which means that you will block some worker thread but not the one you spawned the coroutine from.



          On the other hand, if you were to write this block:



          fun main() 
          runBlocking
          Thread.sleep(1000L)
          println("World!")

          println("Hello,")
          Thread.sleep(2000L)



          you'll see that the coroutine blocks the main thread and the output will show a different result. That is because runBlocking runs on the caller thread main rather than one of the worker pool threads.






          share|improve this answer













          The GlobalScope lets you start coroutines which more-or-less have the same behavior as daemon threads since they are detached from any Coroutine-Job and basically run as long as the application. Their lifecycle is only limited by the application itself. This is something you want to avoid by using "structured concurrency" which basically means that your coroutines should be nested in a way that you can control them without manually keeping track of their references and joining them for example in order to await their computations. So in your real-life code you should avoid GlobalScope as much as possible, since there's most certainly a better solution.



          As to your question, and as already mentioned, the GlobalScope runs on the Dispatchers.Default pool, which means that you will block some worker thread but not the one you spawned the coroutine from.



          On the other hand, if you were to write this block:



          fun main() 
          runBlocking
          Thread.sleep(1000L)
          println("World!")

          println("Hello,")
          Thread.sleep(2000L)



          you'll see that the coroutine blocks the main thread and the output will show a different result. That is because runBlocking runs on the caller thread main rather than one of the worker pool threads.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 26 at 7:37









          s1m0nw1s1m0nw1

          33.6k6 gold badges62 silver badges119 bronze badges




          33.6k6 gold badges62 silver badges119 bronze badges























              0














              The GlobalScope.launch.. function will not block. It returns an Job object, which you may use to wait for a result.



              Behind the scenes, the GlobalScope uses the default dispatcher Dispatchers.Default. You may see it, for example, by printing a thread name inside a launch.. function.



              You will need to run more coroutines to see them blocking each other because of Thread.sleep calls.



              https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html






              share|improve this answer



























                0














                The GlobalScope.launch.. function will not block. It returns an Job object, which you may use to wait for a result.



                Behind the scenes, the GlobalScope uses the default dispatcher Dispatchers.Default. You may see it, for example, by printing a thread name inside a launch.. function.



                You will need to run more coroutines to see them blocking each other because of Thread.sleep calls.



                https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html






                share|improve this answer

























                  0












                  0








                  0







                  The GlobalScope.launch.. function will not block. It returns an Job object, which you may use to wait for a result.



                  Behind the scenes, the GlobalScope uses the default dispatcher Dispatchers.Default. You may see it, for example, by printing a thread name inside a launch.. function.



                  You will need to run more coroutines to see them blocking each other because of Thread.sleep calls.



                  https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html






                  share|improve this answer













                  The GlobalScope.launch.. function will not block. It returns an Job object, which you may use to wait for a result.



                  Behind the scenes, the GlobalScope uses the default dispatcher Dispatchers.Default. You may see it, for example, by printing a thread name inside a launch.. function.



                  You will need to run more coroutines to see them blocking each other because of Thread.sleep calls.



                  https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 25 at 22:40









                  Eugene PetrenkoEugene Petrenko

                  3,22318 silver badges26 bronze badges




                  3,22318 silver badges26 bronze badges





















                      0














                      GlobalScope.launch will not necessarily create a new thread, but it will use one from a shared pool because it uses the Default dispatcher. So, as far as your question is concerned, in your snippet, the block passed to launch runs in a different thread indeed.



                      In the documentation about dispatchers and threads, you will find the following:




                      The default dispatcher, that is used when coroutines are launched in GlobalScope, is represented by Dispatchers.Default and uses shared background pool of threads




                      And in the Dispatchers.Default doc, you can find:




                      By default, the maximal level of parallelism used by this dispatcher is equal to the number of CPU cores, but is at least two. Level of parallelism X guarantees that no more than X tasks can be executed in this dispatcher in parallel.




                      Note that you could change the dispatcher by providing one as a parameter of launch.






                      share|improve this answer

























                      • "but it will use one from a shared pool". Do you imply GlobalScope.launch runs in another thread, if the CPU has at least 2 cores?

                        – user1443721
                        Mar 26 at 3:42











                      • Not really. In fact, the pool contains at least 2 threads, even for single code processors. That what the doc states if I understood correctly.

                        – Joffrey
                        Mar 26 at 7:38















                      0














                      GlobalScope.launch will not necessarily create a new thread, but it will use one from a shared pool because it uses the Default dispatcher. So, as far as your question is concerned, in your snippet, the block passed to launch runs in a different thread indeed.



                      In the documentation about dispatchers and threads, you will find the following:




                      The default dispatcher, that is used when coroutines are launched in GlobalScope, is represented by Dispatchers.Default and uses shared background pool of threads




                      And in the Dispatchers.Default doc, you can find:




                      By default, the maximal level of parallelism used by this dispatcher is equal to the number of CPU cores, but is at least two. Level of parallelism X guarantees that no more than X tasks can be executed in this dispatcher in parallel.




                      Note that you could change the dispatcher by providing one as a parameter of launch.






                      share|improve this answer

























                      • "but it will use one from a shared pool". Do you imply GlobalScope.launch runs in another thread, if the CPU has at least 2 cores?

                        – user1443721
                        Mar 26 at 3:42











                      • Not really. In fact, the pool contains at least 2 threads, even for single code processors. That what the doc states if I understood correctly.

                        – Joffrey
                        Mar 26 at 7:38













                      0












                      0








                      0







                      GlobalScope.launch will not necessarily create a new thread, but it will use one from a shared pool because it uses the Default dispatcher. So, as far as your question is concerned, in your snippet, the block passed to launch runs in a different thread indeed.



                      In the documentation about dispatchers and threads, you will find the following:




                      The default dispatcher, that is used when coroutines are launched in GlobalScope, is represented by Dispatchers.Default and uses shared background pool of threads




                      And in the Dispatchers.Default doc, you can find:




                      By default, the maximal level of parallelism used by this dispatcher is equal to the number of CPU cores, but is at least two. Level of parallelism X guarantees that no more than X tasks can be executed in this dispatcher in parallel.




                      Note that you could change the dispatcher by providing one as a parameter of launch.






                      share|improve this answer















                      GlobalScope.launch will not necessarily create a new thread, but it will use one from a shared pool because it uses the Default dispatcher. So, as far as your question is concerned, in your snippet, the block passed to launch runs in a different thread indeed.



                      In the documentation about dispatchers and threads, you will find the following:




                      The default dispatcher, that is used when coroutines are launched in GlobalScope, is represented by Dispatchers.Default and uses shared background pool of threads




                      And in the Dispatchers.Default doc, you can find:




                      By default, the maximal level of parallelism used by this dispatcher is equal to the number of CPU cores, but is at least two. Level of parallelism X guarantees that no more than X tasks can be executed in this dispatcher in parallel.




                      Note that you could change the dispatcher by providing one as a parameter of launch.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Mar 25 at 22:56

























                      answered Mar 25 at 22:37









                      JoffreyJoffrey

                      7,8781 gold badge29 silver badges53 bronze badges




                      7,8781 gold badge29 silver badges53 bronze badges












                      • "but it will use one from a shared pool". Do you imply GlobalScope.launch runs in another thread, if the CPU has at least 2 cores?

                        – user1443721
                        Mar 26 at 3:42











                      • Not really. In fact, the pool contains at least 2 threads, even for single code processors. That what the doc states if I understood correctly.

                        – Joffrey
                        Mar 26 at 7:38

















                      • "but it will use one from a shared pool". Do you imply GlobalScope.launch runs in another thread, if the CPU has at least 2 cores?

                        – user1443721
                        Mar 26 at 3:42











                      • Not really. In fact, the pool contains at least 2 threads, even for single code processors. That what the doc states if I understood correctly.

                        – Joffrey
                        Mar 26 at 7:38
















                      "but it will use one from a shared pool". Do you imply GlobalScope.launch runs in another thread, if the CPU has at least 2 cores?

                      – user1443721
                      Mar 26 at 3:42





                      "but it will use one from a shared pool". Do you imply GlobalScope.launch runs in another thread, if the CPU has at least 2 cores?

                      – user1443721
                      Mar 26 at 3:42













                      Not really. In fact, the pool contains at least 2 threads, even for single code processors. That what the doc states if I understood correctly.

                      – Joffrey
                      Mar 26 at 7:38





                      Not really. In fact, the pool contains at least 2 threads, even for single code processors. That what the doc states if I understood correctly.

                      – Joffrey
                      Mar 26 at 7:38

















                      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%2f55347302%2fdoes-globalscope-launch-create-a-new-thread-or-run-in-the-same-thread%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

                      Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                      Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                      Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript