I need to detect whether a MongoDB instance is run...
# ktor
c
I need to detect whether a MongoDB instance is running on
localhost:27017
or
mongo:27017
. I thought this would be a good occasion to try out Ktor Network, so I wrote:
Copy code
suspend fun findMongoAddress(): InetSocketAddress {	
    val manager = SelectorManager(currentCoroutineContext())
    val candidateHostNames = listOf("localhost", "mongo")

	println("Searching for the address of the running MongoDB instance…")
	for (hostName in candidateHostNames) {
		val address = InetSocketAddress(hostName, 27017)

		try {
			println("» Trying $address…")
			val opened = aSocket(manager).tcp().connect(address) {
				socketTimeout = 100
			}.use { println("  Connected successfully!") }
			return@shared address
		} catch (e: Exception) {
			println("  Could not connect to MongoDB on socket $address • $e")
		}
	}

	error("Could not find on which port MongoDB is running.")
}
but I'm seeing different behavior on different platforms. On the JVM, I'm seeing:
Copy code
Searching for the address of the running MongoDB instance…
» Trying localhost/127.0.0.1:27017…
  Connected successfully!
and then it hangs indefinitely. I see the same behavior on linuxX64. However, on wasmJs, it doesn't hang, and successfully continues to the rest of the program. What is going on?
o
Looks like its hanging on
socket.close()
. That might be a bug. Note that you are also supposed to close the
SelectorManager
.
a
The full example in the docs also does not close the SelectorManager.
c
^ that example is a server, I'm a client.
Interesting. If I replace the dispatcher from
currentCoroutineContext()
to
Dispatchers.Default
, then it finishes as expected.
I wonder if it's because the socket connection has an infinite loop somewhere that doesn't suspend, and since I'm running in the test dispatcher which is single-threaded
If so, that's a shame, because using the test dispatcher would be quite convenient here
If I give it a Job that is a child of the current job (but still use
Dispatchers.Default
) then it hangs too 🤔
Ok after some setup to be able to use DebugProbes… It's blocked on this line in
ActorSelectorManager
.
Interesting. With this coroutine context, it still hangs on the JVM and passes on Wasm, but now it also passes on LinuxX64.
This works on the three platforms without hanging:
Copy code
val job = Job()
	currentCoroutineContext().job.invokeOnCompletion { e -> job.cancel("Finished searching for the address. (ended with: $e)")}
	val manager = SelectorManager(Dispatchers.Default + job + CoroutineName("FindMongoAddressManager"))
a
You can find the issue here.
o
Wow! That's a concise reproducer. 👏
c
Thanks 🙏 I'll add the other info I found there