So I have this code snippet that I'm using where I...
# getting-started
c
So I have this code snippet that I'm using where I'm doing while(true) and it just feels wrong. is there a better way to do this? I'm working with raw sockets and ktor has a nice-ish api for raw tcp sockets so I'm using that
Copy code
val receiveChannel = socket.openReadChannel()
val sendChannel = socket.openWriteChannel(autoFlush = true)

launch(<http://Dispatchers.IO|Dispatchers.IO>) {
  while (true) {
    println("awaiting readUtf8Line")
    val greeting = receiveChannel.readUTF8Line()
    if (greeting != null) {
      println(greeting)
    } else {
      print("got a line that's null?")
    }
  }
}
its basically copied from https://ktor.io/docs/servers-raw-sockets.html#client-example
s
might be about to Cunningham's Law myself, but if you're writing code at the layer where you're directly blocking on the socket to await incoming bytes, I don't think there's any way to get around the "busy wait" that you have to do
t
One thing you should do is to write
while(isActive)
to support cancellation. https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/is-active.html
c
^ though in this time, the only thing the loop does is call other suspending functions, so my understanding is cancellation is supported just fine. I tend to use
isActive
anyway, if only just to make it clear that the loop is being controlled from the outside.
j
Yeah no need for
isActive
if you call suspend functions that support prompt cancellation. That's just extra noise to look at when reading the code IMO
c
if you call suspend functions that support prompt cancellation
How do I know if a suspend function supports prompt cancellation? I thought the act of calling a suspend function itself supports it
j
I'm not 100% sure, but I believe if a function doesn't actually suspend for instance, you might not get the
CancellationException
when calling it. Most suspend functions will throw though, so it should be fine to assume that it will work most of the time, unless you're calling a function with a
suspend
keyword that isn't actually cancellable. E.g. a suspend function implemented with
suspendCoroutine
instead of
suspendCancellableCoroutine
, or a function marked with
suspend
but that is just a normal blocking function.
👍 1
c
So it has to actually suspend, not just be a suspend-able function?
j
Yes: https://pl.kotl.in/zwl_3v7po But I mean "fake" suspend functions should just not exist, I guess if they never suspend it's actually a bug.
However, suspend functions that don't support cancellation might very well exist (although unusual). And this wouldn't guarantee prompt cancellation... since it doesn't even guarantee cancellation at all, more like guarantees to never cancel 😄 https://pl.kotl.in/aN7chSZbC
But again, this should not be common, and I would by default assume that most suspend functions I use are well-behaved, so no need for
isActive
IMO. Also, just checking for
isActive
wouldn't propagate the cancellation exception (not sure if that has any bad consequence), so maybe a better way would be to use
coroutineContext.ensureActive()
.
today i learned 2