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 ?
compose. Compose this future with a mapper function. When this future (the one on which compose is called) succeeds, the mapper will be called with the completed value and this mapper returns another future object. This returned future completion will complete the future returned by this method call.
Vert. x is a JVM toolkit that can be used to build reactive systems. It is event-driven and uses message passing for processing work; those messages are by default handled by the event loop which is (usually) one thread responsible to find the right handler for an incoming message, and process it.
Promise are for defining non-blocking operations, and it's future() method returns the Future associated with a promise, to get notified of the promise completion and retrieve its value. The Future interface is the result of an action that may, or may not, have occurred yet.
For those who don't know, Vert.x is an event driven and non blocking application toolkit. It's polyglot, so you can use it with different languages (as Java, Kotlin, JavaScript, Groovy, Ruby or Scala ). What does "non blocking" mean? In synchronous programming, when a function is called, the caller has to wait until the result is returned.
Future composition API in Vert.x represents a solid way to write simple and affordable async code. never throw exceptions into async code, use failed future instead to handle failure behaviours. at the end of a future composition, don't forget to handle future's successes ( onSuccess) and failures ( onFailure)
In addition to what we have seen, Vert.x offers also many other functionalities: a Rx API, a standard for reactive streams and fibers, some tools for generating the code or the documentation, integration with Cloud providers such as OpenShift, a Docker integration, some bridges with Service Discovery tools such as Consul etc…
In this first post we covered the core principles of Vert.x: Event loop model, Verticle and Event Bus. As we have seen, Vert.x is a dedicated framework for implementing reactive applications. It’s worth adding as well that the Verticle model fits really well with micro-services concepts.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With