invokeOnClose

abstract fun invokeOnClose(handler: (cause: Throwable?) -> Unit)(source)

Registers a handler which is synchronously invoked once the channel is closed or the receiving side of this channel is cancelled. Only one handler can be attached to a channel during its lifetime. The handler is invoked when isClosedForSend starts to return true. If the channel is closed already, the handler is invoked immediately.

The meaning of cause that is passed to the handler:

  • null if the channel was closed normally without the corresponding argument.

  • Instance of CancellationException if the channel was cancelled normally without the corresponding argument.

  • The cause of close or cancel otherwise.

Execution context and exception safety

The handler is executed as part of the closing or cancelling operation, and only after the channel reaches its final state. This means that if the handler throws an exception or hangs, the channel will still be successfully closed or cancelled. Unhandled exceptions from handler are propagated to the closing or cancelling operation's caller.

Example of usage:

val events = Channel<Event>(UNLIMITED)
callbackBasedApi.registerCallback { event ->
events.trySend(event)
.onClosed { /* channel is already closed, but the callback hasn't stopped yet */}
}

val uiUpdater = uiScope.launch(Dispatchers.Main) {
events.consume { /* handle events */}
}
// Stop the callback after the channel is closed or cancelled
events.invokeOnClose { callbackBasedApi.stop() }

Stability note. This function constitutes a stable API surface, with the only exception being that an IllegalStateException is thrown when multiple handlers are registered. This restriction could be lifted in the future.

Throws

if the underlying channel does not support invokeOnClose. Implementation note: currently, invokeOnClose is unsupported only by Rx-like integrations

if another handler was already registered