[concurrency-interest] ForkJoinPool for async http calls?

Christian Essl christianessl at googlemail.com
Thu May 10 08:12:05 EDT 2012


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.

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
>



More information about the Concurrency-interest mailing list