Vert.x: Verticle 自定义 startFuture 处理程序总是被重写

Vert.x: Verticle custom startFuture handler is always rewritten

Vert.x v3.5.1。 有我的 Verticle 自定义 start 方法:

@Override
public void start(Future<Void> startFuture) throws Exception {
    startFuture.setHandler(event -> {
        if (event.succeeded()) {
            logger.info("Server started on port: {}", 8080);
        } else {
            logger.warn("Failed to start: {}", event.cause());
        }
    });
    vertx.createHttpServer()
            .requestHandler(router()::accept)
            .listen(8080, event -> {
                if (event.succeeded()) {
                    startFuture.complete();
                } else {
                    startFuture.fail(event.cause());
                }
            });
}

我希望在未来完成时调用我的自定义处理程序。但事实并非如此! 在调试模式下,我看到 FutureImpl::setHandler 被调用了两次:一次使用我的自定义处理程序,然后在 doDeploy 期间使用 DeploymentManager 的处理程序。 因此应用了最新的处理程序。

问题是:是否可以为Verticle启动指定自定义回调?如果是,我该怎么做?

提前致谢。

首先,将您的 Verticle 编写为 AbstractVerticle 扩展。并且不要覆盖 start(Future) 方法。而是使用 start() 方法。它将从 AbstractVerticle.start(Future) 调用,您可以在 Vertx.deployVerticle(verticle, options, future) 方法中指定未来。

例如:

你有一些垂直。在里面做start()方法只初始化任务:

@Override
public void start() throws Exception {
    vertx.eventbus().consume(address, m -> {
       // consumer code skipped
    });
}

和垂直注册:

final DeploymentOptions opts = new DeploymentOptions().setWorker(true);
vertx.deployVerticle(verticle, opts, event -> {
    if (event.succeeded()) {
        log.info("Verticle successfully deployed. DeploymentId: " + event.result());
    } else {
        log.error("Verticle failed to deploy. Cause: " + event.cause().getMessage(), event.cause());
    }
});

就这些了:)

您不应该更改 startFuture 的处理程序,因为它归调用者所有。所以简单地说,不要那样做 :) future 用于表示您已完成开始代码,而不是定义完成后应该做什么。

在您的具体示例中,最好在 http 服务器启动后写入日志,然后向 startFuture 指示您已完成代码执行。

@Override
public void start(Future<Void> startFuture) throws Exception {
    vertx.createHttpServer()
         .requestHandler(router()::accept)
         .listen(8080, event -> {
            if (event.succeeded()) {
                logger.info("Server started on port: {}", 8080);
                startFuture.complete();
            } else {
                logger.warn("Failed to start: {}", event.cause());
                startFuture.fail(event.cause());
            }
         });
}