14

I'm following Jenkov's tutorial on vertx. Here I have two files:

MyVerticle.java:

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;

public class MyVerticle extends AbstractVerticle {

    @Override
    public void start(Future<Void> startFuture) {
        System.out.println("MyVerticle started!");
    }

    @Override
    public void stop(Future stopFuture) throws Exception {
        System.out.println("MyVerticle stopped!");
    }
}

and VertxVerticleMain.java:

import io.vertx.core.Vertx;

public class VertxVerticleMain {

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

        vertx.deployVerticle(new MyVerticle());
    }
}

After running VertxVerticleMain.java, I saw "MyVerticle started!" in Eclipse's console but don't know how to call stop in MyVerticle.

Jenkov said that The stop() method is called when Vert.x shuts down and your verticle needs to stop. How exactly do I shut down my Vert.x and stop this verticle? I want to see MyVerticle stopped! in the console.

Diep TL
  • 163
  • 1
  • 1
  • 5
  • I have a _hunch_ that ```stop``` is called as a part of a shutdown hook. What happens when you terminate the console session in eclipse (by clicking the red square in the top right)? – Jorn Vernee Apr 03 '16 at 19:09
  • @JornVernee: I tried that and nothing happened. The cursor stayed where it was and nothing else was printed. – Diep TL Apr 03 '16 at 19:13
  • Did you check out the doc ([link](http://vertx.io/docs/apidocs/))? ```Vertx``` has a method called ```close``` that might work. – Jorn Vernee Apr 03 '16 at 19:18

2 Answers2

19

From the Vert.x docs:

Vert.x calls this method when un-deploying the instance. You do not call it yourself. 

If you run Vert.x from a main method and you terminate the JVM process (by clicking the 'stop' button in Eclipse, for example), Vert.x probably isn't signaled to undeploy the verticles, or the JVM terminates before Vert.x has time to undeploy the verticles.

You can do a number of things to ensure that the verticle will be undeployed and the stop() method will be called:

  1. Start the Verticle using the vertx commandline. When you stop the process (or tell vert.x to stop), Vert.x will make sure that all verticles are undeployed.
  2. You can programmatically undeploy the deployed verticles by fetching the list of deploymentId's and calling undeploy for all id's:

    vertx.deploymentIDs().forEach(vertx::undeploy);
    
  3. You can programmatically tell Vert.x to stop:

    vertx.close();
    
  4. You can add a shutdown hook to make sure that one of the options above is executed on JVM termination:

    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            vertx.close();
        }
    });
    

You can either programmatically undeploy the verticle by calling the Vert.x API, or just stop the Java process, which in term triggers the Vert.x process to stop.

By the way, it's worth asking yourself whether it's really necessary that the stop() method is always called when the process running the verticle stops. You can never be sure that that happens; when the process is forced to stop or killed, the stop() method might not be called.

Bert Jan Schrijver
  • 1,521
  • 10
  • 16
  • I have added `vertx.close()` after `deployVerticle` but I still cannot see output of `stop`. The console did notify that the process was terminated though. – Diep TL Apr 03 '16 at 22:48
  • Deploying verticles is an asynchronous process. So if you call vertx.close() right after deployVerticle, Vert.x only just started deploying the verticle. It probably isn't deployed yet when you call vertx.close(), that's why it won't be undeployed on vertx.close(). So either wait a bit after deployVerticle before you call vertx.close(), or wait for the verticle to be deployed by using the deployVerticle method with a callback on deployment completion: `vertx.deployVerticle(verticle, deployed -> { // called after deployment `}); or use the shutdown hook I mentioned above. – Bert Jan Schrijver Apr 04 '16 at 05:06
  • 1
    Vertx vertx = Vertx.vertx(); vertx.deployVerticle(new Verticle1(), deployed -> { System.out.println("Callback after verticle started"); vertx.close(); }); If you meant to do something like this, it didn't work. – venugopal Jan 26 '18 at 05:44
  • For point number 1: How can we tell Vert.x to stop? Which method we need to call? How do we instruct the Vert.x httpserver to stop gracefully? – Balaji Sudharsanam Feb 02 '21 at 11:10
  • You can tell Vert.x to stop by stopping the Vert.x process. Either stop the container or send a `kill` command to the Vert.x process. Note: if you send a SIGKILL, the process will be terminated directory. If you send a SIGTERM (the default signal for kill), Vert.x will attempt to shutdown gracefully, including stopping the Vert.x httpserver gracefully. I don't think you can stop the Vert.x instance programmatically. You might be able to stop the JVM programmatically. – Bert Jan Schrijver Feb 03 '21 at 13:42
  • That is the question. SIGKILL terminates the vertx jvm and does not run my shutDownhook in which iam trying to do a vertx.close(). When an external force kills the JVM process abruptly, the JVM won't get a chance to execute shutdown hooks. How do i invoke the vertx.close() when the jvm container is SIGKILLed ? – Balaji Sudharsanam Feb 04 '21 at 07:03
  • You can't. When the process is killed, the OS terminates the process and the JVM will terminate without calling any shutdown hooks. The same thing happens when a power loss/cycle occurs on the server your JVM is running on: the process is gone. – Bert Jan Schrijver Feb 08 '21 at 09:38
  • I would start by thinking about why this is a problem and see if you can solve it in another way, or try to influence the kill signal that gets sent to the JVM. Do note that you will still have the same problem in case of a power outage. – Bert Jan Schrijver Feb 08 '21 at 09:39
1

your code should add super.stop() and super.start() function like that:

public class MyVerticle extends AbstractVerticle {

    @Override
    public void start(Future<Void> startFuture) {
        //must call super.start() or call startFuture.complete()
        super.start(startFuture); 
        System.out.println("MyVerticle started!");
        System.out.println("Verticle_stopFuture.start(): deployId=" + context.deploymentID());
    }

    @Override
    public void stop(Future stopFuture) throws Exception {
        //must call super.stop() or call stopFuture.complete()
        super.stop(stopFuture);
        System.out.println("MyVerticle stopped!");
    }
}

and VertxVerticleMain.java:

public class VertxVerticleMain {
    static String verticle_deployId;

    public static void main(String[] args) throws InterruptedException {
        System.out.println("start main(): thread="+Thread.currentThread().getId());


        Vertx vertx = Vertx.vertx();

        vertx.deployVerticle(new MyVerticle(), new Handler<AsyncResult<String>>(){

            @Override
            public void handle(AsyncResult<String> asyncResult) {

                if (asyncResult.succeeded()) { // khi startFuture.complete() đc gọi
                    System.out.println("asyncResult = DeployId =" + asyncResult.result());

                    verticle_deployId = asyncResult.result();
                } else { //khi startFuture.fail() đc gọi
                    System.out.println("Deployment failed!");  //vì chưa đc cấp id
                }
            }
        });

        // waiting for Verticle context is allocate by Vertx
        Thread.currentThread().sleep(500);

        Set<String> deploymentIDs = vertx.deploymentIDs();
        System.out.println("==============  (sleeped 500ms wait for Context allocated), list of deploymentIDs: number Deployments =" + deploymentIDs.size());
        for(String depId: deploymentIDs){
            //
            System.out.println(depId);
        }

        //close verticle here
        vertx.undeploy(verticle_deployId);


    }

}
HungNM2
  • 3,101
  • 1
  • 30
  • 21