[concurrency-interest] ForkJoinPool for async http calls?

Gregg Wonderly gregg at cytetech.com
Thu May 10 08:31:52 EDT 2012


On 5/10/2012 7:12 AM, Christian Essl wrote:
> Hi Viktor,
>
> Thanks for your answer, and thanks for your patient discussion outside
> of the mailing-list.
>
> As said I like the akka-framework, still it would be very nice if
> anybody could answer my original question whether ForkJoinTasks can
> give a sort of non-blocking future also suitable for async IO, because
> I am stil not sure.

I believe that ForkJoin was designed specifically for managing non-blocking, 
compute bound tasks.  Primarily, this issue of "partial failure" in the form of 
I/O failures really complicates things.  Practically, you'd like for your I/O to 
be linearly consistent, so a ForkJoin task, would need to do all the I/O for a 
particular "operation" itself.

Inside of a Servlet container, you really shouldn't be mucking about with 
threading, related to the request completion.  If you have other services to 
interact with, they should be done within a linear progression of code inside of 
the doGet, doPut, doPost etc methods.

The thread which calls doGet/doPost is, already, from a pool which the container 
is managing in some way.  Adding another thread to the mix, to perform some 
work, would require the calling thread to block and wait for it to complete 
anyway, so why not just have the calling thread do that work?

If you do have some compute bound work to do, in some cases, where the 
container, is otherwise idle, or small (not tomcat/glassfish), you might find 
some benefit in using fork/join to do the compute work.  But, again, based on 
the servlet programming model, the doGet/doPost thread, must block, and wait for 
the results, and then write back the response.

Gregg Wonderly

> Thanks,
> Christian
>
> On Mon, May 7, 2012 at 1:55 PM, √iktor Ҡlang<viktor.klang at gmail.com>  wrote:
>> Another prime usecase for composable futures:
>>
>> //Warning pseudocode, not compiled
>>
>> import akka.dispatch.{ Promise, Future }
>> def bridge(httpRequestBuilder: AsyncHttpClient.BoundRequestBuilder):
>> Future[Response] = {
>>    val p = Promise[Response]()
>>    httpRequestBuilder.execute(new AsyncCompletionHandler[Response] {
>> override def onCompleted(resp: Response): Response = p success resp
>> override def onThrowable(t: Throwable): Unit = p failure t
>>    })
>>    p.future
>> }
>>
>> in servlet...
>>
>> bridge(yourRequestBuilder) map asyncCtx.write foreach { _ =>  asyncCtx.close
>> }
>>
>> Cheers,
>>>>
>> On Sun, May 6, 2012 at 11:58 PM, Christian Essl
>> <christianessl at googlemail.com>  wrote:
>>>
>>> Sorry if this is a stupid question regarding fork-join pools, but I am not
>>> sure wheter the "lightweigth future" idea would also work async http calls.
>>> (And please also excuse my bad english)
>>>
>>> Currently I use the ning asnyc-http-client
>>> (https://github.com/sonatype/async-http-client) in an event-driven callback
>>> style to do nonblocking http-calls from a servlet.
>>>
>>> However the callback style gets a bit complicated when the program-logic
>>> gets complex so I wonder wheter I could use ForkJoinTask to transfer the
>>> callback style to non-thread-blocking futures.
>>>
>>> The idea is to initialize the nonblocking HttpCall in ForkJoinTaks.exec()
>>> and when the callback receives the http-response it calls the
>>> ForkJoinTaks.complete() method.
>>>
>>> Maybe someone can take a look at the following ForkJoinTask which wraps an
>>> HttpCall and say wheter it is a reasonable use of ForkJoinPool.
>>>
>>> import com.ning.http.client.AsyncHttpClient;
>>> import com.ning.http.client.AsyncCompletionHandler;
>>> import com.ning.http.client.Response;
>>>
>>> //The forkjoin task which wraps an async-http-call
>>> class HttpTask extends ForkJoinTask<Response>  {
>>>
>>> private Response result;
>>> private AsyncHttpClient.BoundRequestBuilder httpRequestBuilder;
>>> public HttpTask(AsyncHttpClient.BoundRequestBuilder builder) {
>>> //the httpRequestBuilder is setup up by the caller (setting the url etc)
>>>          //and used by HttpTask to execute the http request
>>>          this.httpRequestBuilder = builder;
>>> }
>>> @Override
>>> protected boolean exec() {
>>> try {
>>> //this is non blocking event-style http call
>>> httpRequestBuilder.execute(new AsyncCompletionHandler<Response>() {
>>>
>>> @Override
>>> public Response onCompleted(Response resp) throws Exception {
>>> //when the response is received complete the ForkJoinTask
>>> HttpTask.this.complete(resp);
>>> return resp;
>>> }
>>> @Override
>>> public void onThrowable(Throwable t) {
>>> //wehn exception complete Exceptionally the ForkJoinTask
>>> HttpTask.this.completeExceptionally(t);
>>> }
>>> });
>>> } catch (IOException e) {
>>> throw new RuntimeException(e);
>>> }
>>> return false;
>>> }
>>>
>>> @Override
>>> public Response getRawResult() {
>>> return result;
>>> }
>>>
>>> @Override
>>> protected void setRawResult(Response arg0) {
>>> result = arg0;
>>> }
>>> }
>>>
>>> I than use the HttpTask in Servelt like that:
>>>
>>> public class FooServlet extends javax.servlet.http.HttpServlet {
>>>
>>> private ForkJoinPool forJoinPool = new ForkJoinPool();
>>> private AsyncHttpClient httpClient = new AsyncHttpClient();
>>> @Override
>>> protected void doGet(final HttpServletRequest req, final
>>> HttpServletResponse resp)
>>> throws ServletException, IOException {
>>> final AsyncContext asyncCtxt = req.getAsyncContext();
>>> RecursiveAction action = new RecursiveAction() {
>>> @Override
>>> protected void compute() {
>>> //do the http request
>>> HttpTask t = new HttpTask(httpClient.prepareGet("http//url.to.service/"));
>>>     Response res = t.invoke();
>>> }
>>> };
>>> }
>>> }
>>>
>>> My assumption here is that when the HttpTask is invoked that the
>>> ForkJoinPool does not block the thread until the Response is received but
>>> rather takes another RecursiveAtion to process another request until the
>>> httpresponse arrives.
>>>
>>> My question is wheter my assumptions are right and wheter this is a
>>> reasonable use of ForkJoinPool.
>>>
>>> Thanks for any responses.
>>>
>>>
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> Concurrency-interest at cs.oswego.edu
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>>
>>
>>
>>
>> --
>> Viktor Klang
>>
>> Akka Tech Lead
>> Typesafe - The software stack for applications that scale
>>
>> Twitter: @viktorklang
>>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest



More information about the Concurrency-interest mailing list