Joost Klitsie
04/09/2026, 11:24 AMAlexander Sysoev
04/09/2026, 11:33 AMJoost Klitsie
04/09/2026, 11:34 AMJoost Klitsie
04/09/2026, 11:34 AMAlexander Sysoev
04/09/2026, 11:34 AMAlexander Sysoev
04/09/2026, 11:35 AMJoost Klitsie
04/09/2026, 11:36 AMJoost Klitsie
04/09/2026, 11:38 AMJoost Klitsie
04/09/2026, 11:40 AMJoost Klitsie
04/09/2026, 12:38 PMJoost Klitsie
04/10/2026, 7:45 AMoverride fun run() = println("log me!") didn't print anything but was hanging indefinitely...). If I change the use case to be a singleton it runs -> no idea what is wrong here, maybe koin gets confused when it should supply this use case fast multiple times, I did see this particular use case being instantiated multiple times (per design) concurrently.
Other than that, I changed that my client will first connect with a ping() before making any other calls. In this way, connection is made first before more concurrent requests are made, as I saw in ktor that my route { rpc("..") {} } was called multiple times but only 1 rpc service actually being instantiated, I guess that isn't bad but still I made the change.
My current hypothesis is that perhaps the culprit can be koin -> maybe if multiple rpc services are instantiated and a dependency is quickly constructed multiple times, accross multiple threads (didn't check this but I imagine ktor to handle traffic multithreaded by default), it may cause some form of deadlock. Due to this deadlock, connections aren't handled properly once a service is hit (like what I saw with flows not being cancelled).Joost Klitsie
04/10/2026, 7:53 AMJoost Klitsie
04/10/2026, 1:50 PM/**
* Ugly-ass function to detect socket interruptions
*/
@OptIn(ExperimentalWasmJsInterop::class)
fun applyJsPatch(@Suppress("unused") callback: () -> Unit) {
js("""
(function() {
const OriginalWS = window.WebSocket;
window.WebSocket = function(url, protocols) {
const socket = new OriginalWS(url, protocols);
socket.addEventListener('error', () => {
callback(); // Calls the Kotlin lambda passed in
});
return socket;
};
window.WebSocket.prototype = OriginalWS.prototype;
})();
""")
}
// I call it connection closer, do whatever you want with it :D
fun setupInterruptionDetection(connectionCloser: ConnectionCloser) {
val onInterrupted = {
println("Interruption detected via JS hook!")
connectionCloser.close()
}
applyJsPatch(onInterrupted)
}Joost Klitsie
04/10/2026, 1:51 PMAlexander Sysoev
04/10/2026, 1:52 PM