Skip to content

Instantly share code, notes, and snippets.

@billoneil
Created February 10, 2017 02:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save billoneil/f949def19560f379bec9aa640b19120c to your computer and use it in GitHub Desktop.
Save billoneil/f949def19560f379bec9aa640b19120c to your computer and use it in GitHub Desktop.
package com.stubbornjava.common.concurrent;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import org.jooq.lambda.Unchecked;
import org.jooq.lambda.tuple.Tuple;
import org.jooq.lambda.tuple.Tuple3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
public class Futures {
private Futures() {
}
private static final Logger log = LoggerFactory.getLogger(Futures.class);
private static final CountDownLatch emailLatch = new CountDownLatch(1);
private static final CountDownLatch tagLatch = new CountDownLatch(1);
private static final CountDownLatch roleLatch = new CountDownLatch(1);
public static <T1, T2, T3> Tuple3<T1, T2, T3> joinAll(
CompletableFuture<T1> f1,
CompletableFuture<T2> f2,
CompletableFuture<T3> f3) {
// Do we even need this allOf since we join below anyway.
CompletableFuture.allOf(f1, f2, f3).join();
return Tuple.tuple(f1.join(), f2.join(), f3.join());
}
private static class User {
private final String email;
private final List<String> tags;
private final List<String> roles;
public User(String email, List<String> tags, List<String> roles) {
super();
this.email = email;
this.tags = tags;
this.roles = roles;
}
public String getEmail() {
return email;
}
public List<String> getTags() {
return tags;
}
public List<String> getRoles() {
return roles;
}
}
private static String findEmailById(Long id) {
log.debug("email begin");
Unchecked.supplier(() -> {emailLatch.await(); return null;}).get();
log.debug("email end");
return "test@test.com";
}
private static List<String> findTagsByEmail(String email) {
log.debug("tags begin");
Unchecked.supplier(() -> {tagLatch.await(); return null;}).get();
log.debug("tags end");
return Lists.newArrayList("tag1", "tag2");
}
private static List<String> findRolesByEmail(String email) {
log.debug("roles begin");
Unchecked.supplier(() -> {roleLatch.await(); return null;}).get();
log.debug("roles end");
return Lists.newArrayList("admin", "user");
}
private static User findUserById(long id) throws InterruptedException {
CompletableFuture<String> emailFuture = CompletableFuture.supplyAsync(() -> findEmailById(1L));
CompletableFuture<List<String>> tagFuture = emailFuture.thenApplyAsync(Futures::findTagsByEmail);
CompletableFuture<List<String>> rolesFuture = emailFuture.thenApplyAsync(Futures::findRolesByEmail);
log.debug("tag latch countdown");
tagLatch.countDown();
Thread.sleep(500L);
log.debug("email latch countdown");
emailLatch.countDown();
Thread.sleep(500L);
log.debug("role latch countdown");
roleLatch.countDown();
return Futures.joinAll(emailFuture, tagFuture, rolesFuture).map(User::new);
}
public static void main(String[] args) throws InterruptedException {
User user = findUserById(1L);
log.debug("got user " + user.getEmail());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment