如何在Ktor内部检查Netty实际上已启动?

尼基塔(Nikita Tukkel)

我需要对Ktor应用程序进行一些初始化,但是我只想在Netty准备好接受连接之后再进行。另一方面,如果Netty无法启动(例如,典型的“地址已在使用中”),我不希望进行此类初始化。

我实现了简单的方法(请参见下文),但我想知道是否有可能使它变得不太丑陋

首先,我将引用保存到NettyApplicationEngine:

embeddedServer = embeddedServer(Netty, port, module)

然后,我使用channelsNettyApplicationEngine中字段来确定其状态:

private fun NettyApplicationEngine.channelsReady(): Boolean {
    val channelsField = this::class.members.find { it.name == "channels" }!!
    channelsField.isAccessible = true
    val channels = channelsField.call(this) as List<Channel>?
    return !channels.isNullOrEmpty() && channels.all { it.isActive }
}

最后,我捕获了ApplicationStarted事件并旋转直到通道准备就绪:

environment.monitor.subscribe(ApplicationStarted) {
        thread(start = true, name = "real netty postinit") {
            for (i in 1..100) {
                TimeUnit.MILLISECONDS.sleep(100)
                if (embeddedServer.channelsReady()) break
            }

            if (embeddedServer.channelsReady()) {
                // Initialization here
            } else {
                // Server didn't start
                embeddedServer.stop(1, 1, TimeUnit.SECONDS)
            }
        }
    }
尼基塔(Nikita Tukkel)

在尝试了几种不同的方法之后,我得出了一个自测结论,该测验仅将HTTP请求发送到我自己的端点,并且如果HttpClient和路由处理程序都成功执行,我认为Netty已经准备就绪。

首先,我向注册Routing.RoutingCallFinished事件NettyApplicationEngine.environment.monitordispose稍后创建的处理程序)。

然后,我将全部迭代NettyApplicationEngine.environment.connectors并创建Deferred将从RoutingCallFinished处理程序完成的此外,我启动了异步协程,这些协程将使用HttpClient检查相应的端点。

从那以后,我awaitAll对这些DeferredS(以及DeferredApplicationStarted事件处理为好)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章