```private suspend fun connectAndStartListening() ...
# coroutines
u
Copy code
private suspend fun connectAndStartListening() = coroutineScope {
    val webSocketSession = ktorClient.webSocketSession("<ws://10.0.2.2:8765>")

    launch {
        for (frame in webSocketSession.incoming) {
            Log.d("Default", "frame=$frame")
        }
    }
    ... stuff
}
I want to add graceful closing when this coroutine gets cancelled. How do I listen for cancellation of this function?
Copy code
launch {
   awaitCancellation()
   webSocketSession.close()
}
like this?
z
Copy code
private suspend fun connectAndStartListening() {
    val webSocketSession = ktorClient.webSocketSession("<ws://10.0.2.2:8765>")

    // Assuming the session implements AutoCloseable
    webSocketSession.use {
        coroutineScope {
            launch {
                for (frame in webSocketSession.incoming) {
                    Log.d("Default", "frame=$frame")
                }
            }
            ... stuff
        }
    }
}
u
Copy code
public interface WebSocketSession : CoroutineScope
so.. I dont think so? also now im noticing,
close
is a suspend function
Copy code
public suspend fun WebSocketSession.close(reason: CloseReason = CloseReason(CloseReason.Codes.NORMAL, ""))
z
then replace
use
with try/finally
u
but, which part exactly will throw? I was expecting some sort of callback api
z
Presumably whatever suspends? I’m guessing incoming? I don’t know this api so maybe I’m totally wrong
u
btw if I run a suspend function in finally; doesnt that break the structured concurrency?
z
Nope that’s fine
The coroutine will be in a “canceling” state while finally blocks run and join calls won’t resume until all finally blocks are done.
u
alrighty, thanks !
Copy code
private suspend fun listenAndSend(webSocketSession: DefaultClientWebSocketSession) = coroutineScope {
    val channel = Channel<ByteArray>(capacity = Channel.BUFFERED)
    launch {
        while (isActive) {
            val bytes = queryMicrophone()
            channel.send(bytes)
        }
        channel.close()
    }

    for (bytes in channel) { <-------
        webSocketSession.send(bytes)
    }
}
If I may follow up would you wrap this loop in launch or not?
z
No
👍 1
u
@Zach Klippenstein (he/him) [MOD] sorry to resurect this but I don't think I understand what you meant. Running a suspend function in finally seems to do nothing once the coroutine was cancelled? it hits first suspension point, which throws cancellation exception and rest is a no-op then. So basically it doesnt do anything (?)