Skip to content

Instantly share code, notes, and snippets.

@sujeet100
Last active October 11, 2021 14:44
Show Gist options
  • Save sujeet100/6647e90f916fd42bfccc898b92e877f7 to your computer and use it in GitHub Desktop.
Save sujeet100/6647e90f916fd42bfccc898b92e877f7 to your computer and use it in GitHub Desktop.
Completable Futures
package com.sujit;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
record Person(int id, String name, List<Score> scores, Address address, Account account) {
}
record Score(String subject, int marks) {
}
record Address(String city, String pin) {
}
record Account(String accountNumber, int balance) {
}
public class MyFutures {
public static void main(String[] args) throws ExecutionException, InterruptedException {
final List<String> subjects = List.of("Maths", "Physics");
List<Integer> ids = List.of(1, 2, 3);
List<CompletableFuture<Person>> personsFuture = ids.stream().map(id -> getPerson(subjects, id)).toList();
CompletableFuture<List<Person>> persons = sequence(personsFuture);
System.out.println(persons.get());
}
private static CompletableFuture<Person> getPerson(List<String> subjects, Integer id) {
println("Get Person: " + id);
CompletableFuture<List<Score>> scores = getScores(id, subjects);
CompletableFuture<Address> address = CompletableFuture.supplyAsync(() -> getAddress(id));
CompletableFuture<Account> account = CompletableFuture.supplyAsync(() -> getAccount(id));
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(scores, address, account);
scores.whenComplete((x, e) -> println("Got scores: " + id));
address.whenComplete((x, e) -> println("Got address: " + id));
account.whenComplete((x, e) -> println("Got account: " + id));
return combinedFuture.thenApply(v -> {
println("Got scores, address, account: " + id);
return new Person(id,
"name" + id,
scores.join(),
address.join(),
account.join());
});
}
private static CompletableFuture<List<Score>> getScores(int id, List<String> subjects) {
println("Get Scores: " + id);
List<CompletableFuture<Score>> scoresFuture = subjects.stream().map(subject -> {
CompletableFuture<Score> scoreFuture = CompletableFuture.supplyAsync(() -> getScore(id, subject));
scoreFuture.whenComplete((x, e) -> println("Got score: " + id));
return scoreFuture;
}).toList();
return sequence(scoresFuture);
}
private static Score getScore(int id, String subject) {
println("Get Score: " + id + ", sub: " + subject);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new Score(subject, id * 10);
}
static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> com) {
return CompletableFuture.allOf(com.toArray(new CompletableFuture[0]))
.thenApply(v -> com.stream()
.map(CompletableFuture::join)
.toList()
);
}
private static Address getAddress(int id) {
println("Get Address: " + id);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new Address(id + "City", id + "101");
}
private static Account getAccount(int id) {
println("Get Account: " + id);
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new Account(id + "9090", id * 1000);
}
private static void println(String message) {
System.out.println(Thread.currentThread().getName() + ": " + message);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment