Skip to content

Instantly share code, notes, and snippets.

@AugustNagro
Last active October 21, 2021 06:33
Show Gist options
  • Save AugustNagro/29eaddbd281621a35dcd8b98337d5369 to your computer and use it in GitHub Desktop.
Save AugustNagro/29eaddbd281621a35dcd8b98337d5369 to your computer and use it in GitHub Desktop.
import io.vertx.core.Future;
import io.vertx.core.Promise;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
public class VertxLoomNew {
interface Await {
<A> A await(Future<A> future);
}
static class Coroutine implements Await {
private final ReentrantLock lock = new ReentrantLock();
private final Condition cond = lock.newCondition();
@Override
public <A> A await(Future<A> future) {
lock.lock();
try {
future.onComplete(ar -> {
lock.lock();
try {
cond.signal();
} finally {
lock.unlock();
}
});
cond.await();
if (future.succeeded()) {
return future.result();
} else {
throw new RuntimeException(future.cause());
}
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
public static <A> Future<A> async(Function<Await, A> f) {
Promise<A> promise = Promise.promise();
Thread.ofVirtual().start(() -> {
try {
promise.complete(f.apply(new Coroutine()));
} catch (Exception e) {
e.printStackTrace();
promise.fail(e);
}
});
return promise.future();
}
public static void main(String[] args) {
Future<String> res = async(await -> {
Integer a = await.await(a());
System.out.println("done a");
Integer b = await.await(b());
System.out.println("done b");
Integer a1 = await.await(a());
System.out.println("done a1");
Integer c = await.await(async(await1 -> await1.await(a())));
return "The sum is: " + (a + b + a1 + c);
});
res.onSuccess(System.out::println);
// stop main method from exiting early..
res.toCompletionStage().toCompletableFuture().join();
}
private static Future<Integer> a() {
return Future.fromCompletionStage(CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
return 1;
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
}
private static Future<Integer> b() {
return Future.fromCompletionStage(CompletableFuture.supplyAsync(() -> 2));
}
private static Future<Integer> c() {
return Future.fromCompletionStage(CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("hello world exception");
}));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment