我的应用程序(内部呼叫其他REST服务的典型REST服务器)有两个主要类来执行自举程序。
有 application.kt class 应该配置Vertx实例本身并注册某些模块(例如Jackson Kotlin集成):
class Application(
private val profileSetting: String? = System.getenv("ACTIVE_PROFILES"),
private val logger: Logger = LoggerFactory.getLogger(Application::class.java)!!
) {
fun bootstrap() {
val profiles = activeProfiles()
val meterRegistry = configureMeters()
val vertx = bootstrapVertx(meterRegistry)
vertx.deployVerticle(ApplicationBootstrapVerticle(profiles)) { startup ->
if (startup.succeeded()) {
logger.info("Application startup finished")
} else {
logger.error("Application startup failed", startup.cause())
vertx.close()
}
}
}
}
此外,还有一个 applicationbootstrapverticle.kt class 应该以定义的顺序部署不同的垂直。其中一些按顺序进行,其中一些并行:
class ApplicationBootstrapVerticle(
private val profiles: List<String>,
private val logger: Logger = LoggerFactory.getLogger(ApplicationBootstrapVerticle::class.java)
) : AbstractVerticle() {
override fun start(startFuture: Future<Void>) {
initializeApplicationConfig().compose {
logger.info("Application configuration initialized")
initializeScheduledJobs()
}.compose {
logger.info("Scheduled jobs initialized")
initializeRestEndpoints()
}.compose {
logger.info("Http server started")
startFuture
}.setHandler { ar ->
if (ar.succeeded()) {
startFuture.complete()
} else {
startFuture.fail(ar.cause())
}
}
}
private fun initializeApplicationConfig(): Future<String> {
return Future.future<String>().also {
vertx.deployVerticle(
ApplicationConfigVerticle(profiles),
it.completer()
)
}
}
private fun initializeScheduledJobs(): CompositeFuture {
val stationsJob = Future.future<String>()
val capabilitiesJob = Future.future<String>()
return CompositeFuture.all(stationsJob, capabilitiesJob).also {
vertx.deployVerticle(
StationQualitiesVerticle(),
stationsJob.completer()
)
vertx.deployVerticle(
VideoCapabilitiesVerticle(),
capabilitiesJob.completer()
)
}
}
private fun initializeRestEndpoints(): Future<String> {
return Future.future<String>().also {
vertx.deployVerticle(
RestEndpointVerticle(dispatcherFactory = RouteDispatcherFactory(vertx)),
it.completer()
)
}
}
}
我不确定这是否是引导应用程序的假定方法,如果有的话。不过,更重要的是,我不确定我是否理解未来。
该应用程序成功启动,我看到了除
以外的所有所需的日志消息应用程序启动完成
消息。另外,如果成功:
,以下代码从未称为>}.setHandler { ar ->
if (ar.succeeded()) {
startFuture.complete()
} else {
startFuture.fail(ar.cause())
}
}
如果发生故障,例如,当我的应用程序配置文件(YAML)无法解析时,因为 destination Entity中有一个未知字段,则log Message
应用程序启动失败
出现在日志中,并调用上面的代码。
我很好奇我组成的期货链有什么问题。我认为在以前的未来成功或其中一个失败之后会打电话给处理程序,但我认为这只是在成功的情况下被称为。
update
我想丢失了startFuture.complete()
的调用。通过调整开始方法,它最终起作用:
override fun start(startFuture: Future<Void>) {
initializeApplicationConfig().compose {
logger.info("Application configuration initialized")
initializeScheduledJobs()
}.compose {
logger.info("Scheduled jobs initialized")
initializeRestEndpoints()
}.compose {
logger.info("Http server started")
startFuture.complete()
startFuture
}.setHandler(
startFuture.completer()
)
}
我不确定,如果这是处理这个未来链的假定方法。
对我有用的解决方案看起来像这样:
override fun start(startFuture: Future<Void>) {
initializeApplicationConfig().compose {
logger.info("Application configuration initialized")
initializeScheduledJobs()
}.compose {
logger.info("Scheduled jobs initialized")
initializeRestEndpoints()
}.setHandler { ar ->
if(ar.succeeded()) {
logger.info("Http server started")
startFuture.complete()
} else {
startFuture.fail(ar.cause())
}
}
}