如何在将来的所有未来成功的时候被通知



我的应用程序(内部呼叫其他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())
        }
    }
}

最新更新