The following hangs forever. I would like the suspend function to just return somehow if the send cannot complete.
suspend fun main() = coroutineScope {
    val channel = Channel<Int>()
    
    //channel.close()
    
    launch {
        println("closing")
        channel.close()
    }
    
    channel.send(0) // hangs forever!!
    println("end")
}
So basically what I need is a version of SendChannel.send that just throws or returns when the channel is closed while it's suspended.
 
                        
You said that you would like the
sendfunction to throw or return if the send cannot complete.You have a rendezvous channel with no buffer, so
sendwill always suspend until the channel'sreceivefunction is called. But that doesn't mean that yoursendcall can't complete.Even though the channel is closed,
receivecan still be called to successfully deliver a value that is already "in flight". In that case, the suspendedsendcall will return normally.The channel's order of operations is the same as the order that you called its functions in. A consumer reading from the channel will first see the value
0, and then will reach the end of the channel, becausesendwas called beforeclose.This is mentioned explicitly in the documentation for the
sendfunction of a channel.The
closefunction is part of theSendChannelinterface and is intended for the sender to indicate that it isn't going to send any more values. It doesn't drop values that have already been sent, or are already in the process of being sent.A channel also has a
cancelfunction, which is part of theReceiveChannelinterface. Thecancelfunction is intended for the receiver to indicate that it doesn't want to receive any more values. This will drop all the values that have already been sent, and will cause any ongoingsendattempts to fail with an exception.In your example code, if you replace
channel.close()withchannel.cancel(), the in-flight call tosendwill fail with an exception.