Skip to content

AugustNagro/vertx-async-await

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vertx-Async-Await

Async-Await support for Vertx using Project Loom.

Please note that this project is deprecated in favor of https://github.com/vert-x3/vertx-virtual-threads-incubator

import static com.augustnagro.vertx.loom.AsyncAwait.async;
import static com.augustnagro.vertx.loom.AsyncAwait.await;

Future<byte[]> buildPdf() {
  return async(() -> {
    
    List<Long> userIds = await(userIdsFromDb());
    
    List<String> userNames = new ArrayList<>(userIds.size());
    for (Long id : userIds) {
      userNames.add(await(userNameFromSomeApi(id)))
    }
    
    byte[] pdf = await(somePdfBuilder(userIds))
  
    System.out.println(userIds);
    return pdf;
  });
}

vs.

Future<byte[]> buildPdf() {
  return userIdsFromDb().flatMap(userIds -> {
    Future<List<String>> userNamesFuture =
      Future.succeededFuture(new ArrayList<>());
  
    for (Long userId : userIds) {
      userNamesFuture = userNamesFuture.flatMap(list -> {
        return userNameFromSomeApi(userId)
          .map(userName -> {
            list.add(userName);
            return list;
          });
      });
    }
  
    return userNamesFuture.flatMap(userNames -> {
      return buildPdf(userNames)
        .onComplete(__ ->
          System.out.println("Generated pdf for user ids: " + userIds)
        );
    });
});

Maven Coordinates

<dependency>
  <groupId>com.augustnagro</groupId>
  <artifactId>vertx-loom</artifactId>
  <version>0.2.2</version>
</dependency>

This library requires a JDK 18 Loom Preview Build and depends on vertx-core v. 4.2.4.

JDK 18 is used instead of the new 19 previews because no IDEs work with 19 yet.

WARNING: this library uses class Continuation, which has recently been made private in the Loom OpenJDK fork. It is likely that Continuation will return later in some form, either with a restricted API or virtual thread schedulers. In newer preview builds, we will use --add-exports to get access.

Docs:

async(Callable<A>) returns Future<A>. Within the provided Callable, you can await Futures and program in an imperative style. Stack traces are also significantly improved in the case of errors.

The execution context remains on the current thread; no new threads, virtual or otherwise, are created by calling async.

Finally, async and await calls can be nested to any depth although recursion is not stack-stafe.

Why Async-Await?

Vertx is great as-is.

But there are some downsides too.

  • Using Futures is harder to read & maintain than simple blocking code.
  • It's hard to debug big Future chains in IDEs
  • Stack traces are poor, especially if the Exception is thrown on a different thread than your current Vertx Context. For example, when pgClient.prepareQuery("SELEC * FROM my_table").execute() fails, any logged stacktrace won't show you where this code is. This is because the postgres client maintains its own pool of threads.

Project Loom solves all three issues. The goal of this project is to combine the performance of Vertx's event loop with the productivity of Loom's synchronous programming model.

Testing Notes:

  • the io.vertx.ext.unit.junit.RunTestOnContext JUnit 4 rule is not working with this. See the simple implementation of asyncTest in this project.

About

Async-Await support for Vertx using Project Loom

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages