How to check inside Ktor that the Netty is actually started?

Nikita Tukkel

I need to do some initialization of my Ktor app, but I want to do it only after Netty is ready to accept connections. From the other hand, I don't want such initialization to happen if Netty failed to start (with the typical "address already in use", for example).

I implemented the straightforward approach (see below), but I wonder if it possible to make it the less ugly way?

First I save the reference to NettyApplicationEngine:

embeddedServer = embeddedServer(Netty, port, module)

Then I use the channels field from NettyApplicationEngine to determine its state:

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 }
}

And, finally, I catch the ApplicationStarted event and spin until channels are ready:

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

After trying several different approaches, I concluded with a self-test which simply sends HTTP request to my own endpoint and if both HttpClient and route handler performed successfully, I consider Netty is ready.

First I register Routing.RoutingCallFinished event with NettyApplicationEngine.environment.monitor (I dispose the created handler later).

Then I iterate all NettyApplicationEngine.environment.connectors and create Deferreds that will be completed from the RoutingCallFinished handler. Also, I launch async coroutines that will check corresponding endpoints with HttpClient.

After that I awaitAll on those Deferreds (and on Deferred from ApplicationStarted event handler as well).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Ktor: How to check authentication inside a route handler?

How to check if application has started inside container

Check how a script was started

How to check, find and see the values of a specific column inside of a big database with many tables, if the column actually exists

How to check if email actually exists

Check if click event was started inside an element

How to check if game was started once

How to check if BitmapImage created by Uri is actually an image?

How to check if spark actually parallelizes the job?

How to check if the delayed job is actually retrying

How to check if docker pull actually pulled something

How to check if an element is actually holding some data

How to know if a Constraint is actually with CHECK in SQL Server

How to check if uploaded image is actually an image

How to check if a folder is actually an alias in C (macOS)?

How to fix 'Neither port nor sslPort specified' throw by io.ktor.server.engine.CommandLineKt in a gradle/kotlin/netty project?

Python how to check if a thread has already started

How to check that Zookeeper server is started using Curator?

How to check if a process started in the background still running?

How to check if python unit test started in PyCharm or not?

How to check if webview YouTube video player was started

how to check if a user started a bot in telegram or not?

How to check whether tomcat server is started up

Android VpnService - How to check VpnService if it was started?

How to check if a new process started in windows?

How to use refershToken in ktor

How to add a anchor <a> in KTOR?

How can I do so that css styles are actually inside container?

How to get closest point from a polygon that is ACTUALLY inside the polygon in Postgis