New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Java 8 CompletableFuture<T> as suppliment to Future+CompletionHandler #399

Closed
tnn opened this Issue Oct 8, 2013 · 6 comments

Comments

Projects
None yet
4 participants
@tnn
Copy link

tnn commented Oct 8, 2013

JDK 8 introduces a composable standard Future called CompletableFuture[1]. Even through it will be a pain to support this while retaining backwards compatibility, adding support for this standard future is very important when designing complete async systems. It enables the same returned Future to be reused, composed[2] and simplifies the usage of AsyncHttpClient.

Example usage:

asyncHttpClient.prepareGet(url)
    .exceuteJava8Style()
    .thenApply(res -> doStuff(res))
    .exceptionally(e -> log.error("Got exception", e));

[1] http://download.java.net/jdk8/docs/api/java/util/concurrent/CompletableFuture.html
[2] http://nurkiewicz.blogspot.dk/2013/05/java-8-completablefuture-in-action.html

@slandelle

This comment has been minimized.

Copy link
Contributor

slandelle commented Oct 8, 2013

As you said, there's the point of compatibility, and we can't target JDK 8 for the standard AHC API.

Note that you can register listeners on the ListenableFuture (that we might refactor for AHC2) and you can probably write an adapter for CompletableFuture from there, even with AHC 1 API.

@ixtli

This comment has been minimized.

Copy link

ixtli commented Nov 21, 2014

I ended up here after researching a clean way to batch requests and only continue once they all return. The java 8 way appears to be CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])); which only resolves once everything in the futures array is complete. Is there an alternative recommended way to wait until multiple requests return AHC that hopefully doesn't require spawning a bunch of threads?

@slandelle

This comment has been minimized.

Copy link
Contributor

slandelle commented Nov 21, 2014

@ixtli Quite easy to implement yourself with some listeners on the ListenableFutures and CountdownLatch.

@ixtli

This comment has been minimized.

Copy link

ixtli commented Nov 21, 2014

Sweet! I'll look into it :)

@alinpopa

This comment has been minimized.

Copy link

alinpopa commented Feb 5, 2015

What about using a CompletableFuture as a Promise, something like this:

public <T> CompletableFuture<T> get(String url, Function<Response, T> supplier){
    final CompletableFuture<T> toBeCompleted = new CompletableFuture<>();
    asyncHttpClient.prepareGet(url).execute(new AsyncCompletionHandler<Response>() {
        @Override
        public Response onCompleted(Response response) throws Exception {
            toBeCompleted.complete(supplier.apply(response));
            return response;
        }
        @Override
        public void onThrowable(Throwable t){
            toBeCompleted.completeExceptionally(t);
        }
    });
    return toBeCompleted;
}

final Function<Response, String> responseProducer = (response) -> {
    try {
        return response.getResponseBody();
    } catch (Exception e) {
        return e.getMessage();
    }
};

final CompletableFuture<String> f =
    get("http://127.0.0.1:8080/bla1", responseProducer)
        .thenCompose(response -> get("http://127.0.0.1:8080/" + response, responseProducer);

That's the alternative that I found ... not sure if it's the best, what do you think?

@slandelle

This comment has been minimized.

Copy link
Contributor

slandelle commented Feb 5, 2015

Yep, that's the way to do it until we target JDK8 (which won't sadly happen in a near future).

@slandelle slandelle self-assigned this Oct 5, 2015

@slandelle slandelle added the AHC2 label Oct 5, 2015

@slandelle slandelle closed this in 3aa6369 Oct 5, 2015

@slandelle slandelle added this to the 2.0.0 milestone Oct 5, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment