Verticles

Verticles are chunks of code that get deployed and run by Vert.x. A Vert.x instance maintains N event loop threads (where N by default is core*2) by default. Verticles can be written in any of the languages that Vert.x supports and a single application can include verticles written in multiple languages.

An application would typically be composed of many verticle instances running in the same Vert.x instance at the same time. The different verticle instances communicate with each other by sending messages on the event bus.

To create a verticle in JAVA, the class must implement io.vertx.core.Verticle interface, or any one of its subclasses.

Example#1:

REACTICA reactive programming
package zjc.examples.vertx.verticle;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;

public class SampleVerticle extends AbstractVerticle {
    private long startTime = System.currentTimeMillis();
    private long counter = 1;
    
    @Override
    public void start() {
        vertx.setPeriodic(2000, counter -> {
            long runTime = (System.currentTimeMillis() - startTime) / 1000;
            System.out.println("Server run time: " + runTime + " seconds.");
        });

        vertx.createHttpServer()
            .requestHandler(req -> {
                System.out.println("Request #" + counter++ +
                                   " from " + req.remoteAddress().host());
                req.response().end("Hello from SampleVerticle!");
            })
            .listen(8080);
        
        System.out.println("==================================================");
        System.out.println("=== SampleVerticle listening on localhost:8080 ===");
        System.out.println("==================================================");
    }

    @Override
    public void stop() {
        System.out.println("===================================");
        System.out.println("=== SampleVerticle signing off! ===");
        System.out.println("====================================");
    }
    
    public static void main (String[] args) {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(new SampleVerticle());
    }
}

Notice that we @Override the start() and stop() methods from AbstractVerticle. Overriding the start() method is typical because you probably want to set up some things when your verticle is loaded. Overriding stop() is less common, but notice that typing Ctrl+C at the command line invoked the stop() method before the system killed the code.  

Once this verticle is up and running, it does two things simultaneously: it uses vertx.setPeriodic() to print a message every two seconds (2000 milliseconds) to indicate how long the code has been running, and it uses vertx.createHttpServer() to serve up requests to localhost:8080.

Second, the print statements in the start() method were executed before the verticle was up and running. The Vert.x runtime doesn’t print the “Succeeded in deploying verticle” message until the start() method is finished. The output says the code is listening on port 8080, but that’s not technically true until a fraction of a second later when the verticle is fully loaded. 

Finally, the verticle contains two asynchronous processes. One (vertx.setPeriodic()) is invoked every two seconds, the other (vertx.createHttpServer()) is invoked whenever an HTTP request comes in on localhost:8080. As long as the verticle is running, these two processes operate independently of each other.

Vert.x Maven Plugin

The maven-vertx-plugin is a plugin for Apache Maven for packaging and running Vert.x applications. The plugin tries provide an opinionated way to build Vert.x application:

  • applications are packaged as a fat jar (containing your code and all the dependencies including Vert.x)
  • the application is configured with an application.json file or an application.yml file (translated to json).

The last version of the Vert.x Maven Plugin is 1.0.28.

The plugin provides a set of goals such as:

  • setup – add the Vert.x Maven Plugin to your pom.xml
  • initialize – manage js dependencies and webjars, also initiates the redeployment
  • package – package your Vert.x application as a fat jar
  • run – run your application
  • start / stop – start your application in background / stop it
Source Code: http://jreact.com/index.php/2023/11/21/vertx-verticle-example-01/

Example#2:

public class HelloVerticle extends AbstractVerticle {
    private static final Logger LOGGER = LoggerFactory.getLogger(HelloVerticle.class);

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(new HelloVerticle());
    }

    @Override
    public void start() {
        LOGGER.info("Welcome to Vertx");
    }

    @Override
    public void stop() {
        LOGGER.info("Shutting down application");
    }
}

Output:

INFO: Welcome to Vertx
Source Code: http://jreact.com/index.php/2023/11/22/vertx-verticle-example-02/

Example#3

public class MainVerticle extends AbstractVerticle {
    private static final Logger LOGGER = LoggerFactory.getLogger(MainVerticle.class);

    @Override
    public void start(Promise<Void> promise) {
        final Router router = Router.router(vertx);
        buildHttpServer(vertx, promise, router);
    }

    private void buildHttpServer(Vertx vertx,
                                 Promise<Void> promise,
                                 Router router) {
        vertx.createHttpServer()
                .requestHandler(router)
                .listen(8080, http -> {
                    if (http.succeeded()) {
                        promise.complete();
                        LOGGER.info(LogUtils.RUN_HTTP_SERVER_SUCCESS_MESSAGE.buildMessage(8080));
                    } else {
                        promise.fail(http.cause());
                        LOGGER.info(LogUtils.RUN_HTTP_SERVER_ERROR_MESSAGE.buildMessage());
                    }
                });
    }
}

Promise/Future

  • futures represent the “read-side” of an asynchronous result,
  • promises represent the “write-side”.

They shall be used for simple coordination of asynchronous tasks, and especially those of:

  • deploying verticles
  • and checking if they were successfully deployed or not.

With the start method of a verticle, prepare the database, then start the webserver:

@Override
public void start(Promise<Void> promise) throws Exception {
	Future<Void> steps =
	  prepareDatabase()
	  .compose(v -> startHttpServer());
	steps.setHandler(promise);
}

Router

A Router, when receives a request, looks for the matching route, and passes the request further. The routes having a handler method associated with it to do sumthing with the request.

Source Code: http://jreact.com/index.php/2023/11/23/vertx-verticle-example-03/