vert.x

Vert.x: How to wait for a future to complete


Is there a way to wait for a future to complete without blocking the event loop?

An example of a use case with querying Mongo:

Future<Result> dbFut = Future.future();
mongo.findOne("myusers", myQuery, new JsonObject(), res -> {
    if(res.succeeded()) {
      ...
      dbFut.complete(res.result());
    }
    else {
      ...
      dbFut.fail(res.cause());
    }
  }
  });

// Here I need the result of the DB query
if(dbFut.succeeded()) {
  doSomethingWith(dbFut.result());
}
else {
  error();
}

I know the doSomethingWith(dbFut.result()); can be moved to the handler, yet if it's long, the code will get unreadable (Callback hell ?) It that the right solution ? Is that the omny solution without additional libraries ?

I'm aware that rxJava simplifies the code, but as I don't know it, learning Vert.x and rxJava is just too much.

I also wanted to give a try to vertx-sync. I put the dependency in the pom.xml; everything got downloaded fine but when I started my app, I got the following error

maurice@mickey> java \
  -javaagent:~/.m2/repository/co/paralleluniverse/quasar-core/0.7.5/quasar-core-0.7.5-jdk8.jar \
  -jar target/app-dev-0.1-fat.jar \
  -conf conf/config.json 
Error opening zip file or JAR manifest missing : ~/.m2/repository/co/paralleluniverse/quasar-core/0.7.5/quasar-core-0.7.5-jdk8.jar
Error occurred during initialization of VM
agent library failed to init: instrument

I know what the error means in general, but I don't know in that context... I tried to google for it but didn't find any clear explanation about which manifest to put where. And as previously, unless mandatory, I prefer to learn one thing at a time.

So, back to the question : is there a way with "basic" Vert.x to wait for a future without perturbation on the event loop ?


Solution

  • You can set a handler for the future to be executed upon completion or failure:

    Future<Result> dbFut = Future.future();
    mongo.findOne("myusers", myQuery, new JsonObject(), res -> {
        if(res.succeeded()) {
          ...
          dbFut.complete(res.result());
        }
        else {
          ...
          dbFut.fail(res.cause());
        }
      }
      });
    
    dbFut.setHandler(asyncResult -> {
        if(asyncResult.succeeded()) {
          // your logic here
        }
    });
    

    This is a pure Vert.x way that doesn't block the event loop