WSClient and thread pool

307 views
Skip to first unread message

doc...@paradigmadigital.com

unread,
Oct 26, 2017, 3:53:40 AM10/26/17
to Play Framework
Ey guys, I have been struggling the last days with a question...

So as I understand, when you do something like
CompletableFuture.supplyAsync(()-> myMethod())

in java 8 you would execute myMethod in the common fork join pool, but play! framework execute it in the executor of its default dispatcher. So basically if you are in the thread A of the executor you would execute it on a thread B, BUT you will loose the http context. Play offers us the class HttpExecutionContext that will allows us to provide the executor of the default dispatcher with the http context too...
CompletableFuture.supplyAsyn(()->myMethod(), httpExecutionContext.current())

With this way, we can "jump" from thread B to thread C with CompletableFuture api and move the context to them too.

Now my question is, what happens when we use the WS api? So I have the following code:
CompletationStage<WSResponse> responsePromise = client.url("url").get();
responsePromise
.thenApply(response -> myMethod(response)


I think the `get` method is executed async by netty. It returns a CompletationStage... So where am I when I execute this method? Did a jump to another thread of the executor of the default dispatcher? Did I stay in the same thread? Am i in a different pool just created for WS work? Do i have the http context when I do thenApply?

Greg Methvin

unread,
Oct 26, 2017, 4:37:46 AM10/26/17
to play-framework
On Thu, Oct 26, 2017 at 12:53 AM, <doc...@paradigmadigital.com> wrote:
Ey guys, I have been struggling the last days with a question...

So as I understand, when you do something like
CompletableFuture.supplyAsync(()-> myMethod())

in java 8 you would execute myMethod in the common fork join pool, but play! framework execute it in the executor of its default dispatcher.

Actually there is no difference in behavior whether you're in a Play app or not. This will always execute on the common ForkJoinPool. This is just the way the CompletableFuture API works.
 
So basically if you are in the thread A of the executor you would execute it on a thread B, BUT you will loose the http context. Play offers us the class HttpExecutionContext that will allows us to provide the executor of the default dispatcher with the http context too...
CompletableFuture.supplyAsyn(()->myMethod(), httpExecutionContext.current())

With this way, we can "jump" from thread B to thread C with CompletableFuture api and move the context to them too.

Right, HttpExecutionContext is just a helper that delegates to an Executor. The one that's bound by default uses the default dispatcher. It captures the context in the current thread and sets it in the new thread.
 

Now my question is, what happens when we use the WS api? So I have the following code:
CompletationStage<WSResponse> responsePromise = client.url("url").get();
responsePromise
.thenApply(response -> myMethod(response)


I think the `get` method is executed async by netty. It returns a CompletationStage... So where am I when I execute this method? Did a jump to another thread of the executor of the default dispatcher? Did I stay in the same thread? Am i in a different pool just created for WS work? Do i have the http context when I do thenApply?

The CompletionStage is actually completed inside the Netty thread pool of the AsyncHttpClient. As for thenApply, you should really only use that when you're running a cheap operation and you don't care where it's run (see https://stackoverflow.com/questions/46060438/in-which-thread-does-completablefutures-completion-handlers-execute-in for some explanation on where it actually runs). If you want to control where it's executed use thenApplyAsync and pass the httpExecutionContext.current() explicitly.

Generally you shouldn't need to care where a CompletionStage you get from another API is actually completed or which thread it runs on.

--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/8abb7ba7-0fac-4339-af22-6df2ecdfce2d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Greg Methvin
Tech Lead - Play Framework

doc...@paradigmadigital.com

unread,
Oct 26, 2017, 6:24:13 AM10/26/17
to Play Framework
Thanks very much. I actually need where the task is done since we need the http context in many parts of our application...

Alexandr Sova

unread,
Oct 28, 2017, 2:22:58 PM10/28/17
to Play Framework
> I actually need where the task is done since we need the http context in many parts of our application.
And do you really have to need for it? Maybe it's better to grab dependencies out from there and do not show http context outside of http controller? Than you wouldn't have to bother about which thread your web service call finishes on etc., you would be able to schedule long-running ws calls to dedicated thread and think about http context only when dealing with requests/replies.

doc...@paradigmadigital.com

unread,
Oct 28, 2017, 3:26:01 PM10/28/17
to Play Framework
Definitely I would like to find a different work around. I need the http context in 2 frames. First, I need it to log some headers on the request through markers. Second, I also need the context in a WSRequestFilter in order to propagate the header to the request.

Inside of my services you will not see the word http, but now I have to be aware that my context needs to be available. If I extract the values that I need in my context the signature of the methods will be too big. I prefer to call the http context directly.

alex....@gmail.com

unread,
Feb 13, 2019, 12:01:19 PM2/13/19
to Play Framework [deprecated]
I'm just like you and I'm worried about the fact that in version 2.7 Http.Context has been deprecated. 


Does anyone know how we could deal with this? 

Igmar Palsenberg

unread,
Feb 13, 2019, 4:13:07 PM2/13/19
to Play Framework [deprecated]
 
I'm just like you and I'm worried about the fact that in version 2.7 Http.Context has been deprecated. 


Does anyone know how we could deal with this?

There is not much to deal with : You now get it as a param on your request method. <= 2.6 needed some black magic to ensure that the current thread has access. Now just just pass them around.

Igmar 
Reply all
Reply to author
Forward
0 new messages