So I'm using this to suspend the current coroutine...
# ktor
j
So I'm using this to suspend the current coroutine until the server stops, which works but for some reason the
ApplicationStopPreparing
listener gets called twice. (1) When the server was stopped and the coroutine resumed and (2) When the compose application closes and I get a
Already resumed, but proposed with update kotlin.Unit
exception
Copy code
suspendCancellableCoroutine {
    server.monitor.subscribe(ApplicationStopPreparing) { _ ->
        it.resume(Unit)
        timeoutScope.cancel()
    }
    server.start()
    it.invokeOnCancellation { _ -> 
        server.stop()
        timeoutScope.cancel()
    }
}
Any idea why this listener gets called on application exit? The server should be down, no?
s
Where is this function called from? I think if this function got cancelled already, then you will also get
Already resumed, but proposed with update kotlin.Unit
. What is your use-case? If you're playing with shutdown and coroutines perhaps this might interest you. https://github.com/arrow-kt/suspendapp?tab=readme-ov-file#suspendapp-with-ktor
j
Yea so that server is basically a one-time use for receiving a OAuth callback, shutting down after getting a successful callback or after timing out. Its probably not getting cleaned up properly Server: https://github.com/supabase-community/supabase-kt/blob/fix-oauth-desktop/Auth/src/[…]kotlin/io/github/jan/supabase/auth/server/HttpCallbackServer.kt Routes: https://github.com/supabase-community/supabase-kt/blob/fix-oauth-desktop/Auth/src/[…]kotlin/io/github/jan/supabase/auth/server/HttpCallbackRoutes.kt suspendapp seems interesting, will take a look
s
Ah, I see what you’re trying to do. I’ve done something similar once. I think that when the function gets cancelled then you call
server.stop
but that in turn calls
subscribe(ApplicationStopPreparing)
and then you
resume
after
invokeOnCancellation
got called. Which is a violation of the contract, and hence you see that exception. You can probably safely ignore that exception though, or introduce a
val isCancelled = AtomicBoolean(false)
to avoid that scenario, and see if it still occurs.
j
Alright thanks!