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