Introduce to Eclipse Vert.x

Hüseyin Akdoğan
5 min readJul 13, 2018

--

Eclipse Vert.x is an event-driven and non-blocking toolkit for developing reactive applications on JVM. It was designed for asynchronous communications.

The most basic benefit of Vert.x is handling a lot of concurrencies using a small number of kernel threads by the event-driven and non-blocking approach. In this way it lets your app scale with minimal hardware.

As known, in the synchronous I/O threading model, a network communication is managed by allocating a thread to each client. This means that a thread assigned to a client deals with the client until it disconnects. Whereas, you can write code as a single thread application with Vert.x because of its providing an event-based programming model.

Vert.x core library defines the basic APIs for writing asynchronous networked applications and also supports polyglot applications that means you can including multiple languages in your applications.

In addition, Vert.x contains several components. You can use any component with all the usual libraries if you want. Vert.x will not restrict you in this regard.

Vert.x Core

Vert.x core contains base functionality supporting such as HTTP, TCP, file system access, and various other features and it’s used by many of the other components of Vert.x. Since the component is just a regular Jar library, you can be embedded to inside your applications.

To use Vert.x core in a Maven project, you will need to add the following dependency to pom.xml

<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>3.5.2</version>
</dependency>

Or, for a Gradle project

dependencies {
compile 'io.vertx:vertx-core:3.5.2'
}

Core Concepts

Vert.x has core concepts.

  • Verticle
  • Event Loop
  • Event Bus

Verticle

A verticle is a unit of deployment in Vert.x and it’s executed within Vert.x instance. Verticles allow you to encapsulate your code for different needs and they are can be run completely independently of each other. Every Vert.x instance has N number of event loop. By default this number is core * 2.

There are three different types of verticles in Vert.x, these

  • Standard Verticles
  • Worker Verticles
  • Multi-threaded Worker Verticles

Standard Verticles are executed using an event loop thread and they are the most common and useful type. Worker Verticles run using a thread from the worker pool. It is never executed concurrently by more than one thread. Multi-threaded Worker Verticles run using a thread from the worker pool like Worker Verticles but they can be executed concurrently by more than one thread differently.

You can have more than one verticle in your application(It will usually). These verticles communicate with each other by sending messages on the event bus.

In addition, as we mentioned, Vert.x supports polyglot hence you can have verticles which are written in any of the languages that Vert.x supports.

Event Loop

The event loop of Vert.x similar to that existing in asynchronous programming models. In this model, every event will be handled in a reasonable amount of time to not block the event loop because Vert.x has a golden role: Don’t block the event loop.

The event loop should not be blocked because when this happens, then that event loop will not be able to do anything else. This means your application will grind to a complete halt when you block all of the event loops in Vert.x instance. At this point, Vert.x has a solution(executeBlocking method) for situations where blocking is inevitable such as a long-lived database operation or complex calculation operations etc.

Because every event loop is attached to a thread and every regular verticle always processes events on the same thread no need to thread coordination mechanisms in Vert.x.

Event Bus

The event bus is the nervous system of Vert.x. We usually have more than one verticle for different needs such as managing access to the database and handling HTTP requests etc in our applications. In this situation, vertical communication will through asynchronous message passing provided over the event bus. Hence, there is a single event bus instance for every Vert.x instance

The event bus supports the following communication modes.

  • point to point messaging
  • request-response messaging
  • publish/subscribe for broadcasting messages

The event bus API performs registering, unregistering handlers and sending, publishing messages operations.

Let’s Code

A verticle class must implement the verticle interface but implement it directly isn’t mandatory. Instead of, you can extend the abstract class AbstractVerticle.

public class HelloWorldVerticle extends AbstractVerticle {  @Override
public void start(Future<Void> future) {
vertx.createHttpServer()
.requestHandler(r -> r.response()
.end("Hello from Vert.x application")).listen(8080,
result -> {
if (result.succeeded()) {
future.complete();
} else {
future.fail(result.cause());
}
});
}
}

The HelloWorldVerticle class extends AbstractVerticle. In this way, the class gets access to the protected vertx field, and the Vert.x instance on which the verticle is deployed.

The start method will call by Vert.x when the verticle deployed and when the method has completed successfully the verticle will be considered started.

The method receives a Future object that represents the result of an action that may, or may not, have occurred yet. It lets us notify Vert.x when the steps in the start method has been completed or reports an error if anything bad happens.

Inside the method, we created an HTTP server which is bound to the 8080 port and assigned a request handler to it. The request handler is called every time the server receives a request. If everything is ok you can see “Hello from Vert.x application” sentence when the visit to http://localhost:8080 after the code running. But when anything bad happens, Vert.x calls future.fail to report an error.

Deploy Verticle

A vertical can be deployed using the deployVerticle method.

public static void main(String[] args){   Vertx vertx = Vertx.vertx();
vertx.deployVerticle(new HelloWorldVerticle(), res -> {
if (res.succeeded()) {
log.info("Deployment id is: " + res.result());
} else {
log.info("Deployment failed!");
}
});
}

At this point, I want to go back to the start method in HelloWorldVerticle and underline a point.

@Override
public void start(Future<Void> future) {
vertx.createHttpServer()
.requestHandler(r -> r.response()
.end("Hello from Vert.x application")).listen(8080,
result -> {
if (result.succeeded()) {
future.complete();
} else {
future.fail(result.cause());
}
});
}

The future parameter is important in terms of notification of the completion process. We as mentioned, Vert.x is asynchronous and non-blocking. This means when the HelloWorld verticle deployed it won’t wait until the start method has been completed. If becomes comment line the future.complete(); in the above code, the following output does not occur.

[vert.x-eventloop-thread-1] INFO Starter — Deployment id is: 704a31b4–9de9–41b7–9411–8d5c07a60465

Keep in mind, Vert.x also has a start method version without the Future parameter. When using this method, Vert.x considers the verticle deployed when the start method returns.

Conclusion

Vert.x offers an elegant way to avoid bottlenecks in many concurrent connections using by a solid foundation to use asynchronous paradigm. In this way, ıt lets your app scale with minimal hardware. In addition, it is lightweight and flexible. The code developed in this article is available on this repository.

References

--

--