Vert.x: Обработчик Verticle custom startFuture всегда переписывается
Vert.x v3.5.1. Есть мой обычай 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
вызывается дважды: один раз с моим пользовательским обработчиком, а затем с DeploymentManager
Обработчик во время doDeploy
, Так что применяется последний обработчик.
Вопрос: можно ли указать собственный обратный вызов для запуска Verticle? Если да, как я могу это сделать?
Заранее спасибо.
2 ответа
Вы не должны изменять обработчик startFuture, поскольку он принадлежит вызывающей стороне. Проще говоря, не делайте этого:) Будущее используется, чтобы сигнализировать, что вы закончили с вашим стартовым кодом, а не определять, что должно быть сделано, когда вы закончите.
В вашем конкретном примере было бы лучше записать журналы, как только 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());
}
});
}
Сначала напишите свою вертикалку как расширение 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());
}
});
Это все:)