Recently I saw an interesting combination usage of Mutex
and suspendCancellableCoroutine
. This combination produces queue-like behaviour where it processes one-at-a-time in FIFO order even though there is no pop()
/ peek()
or explicit queue data structure.
If you have used Snackbar
in Jetpack Compose, you have experienced this combination already (link). SnackbarHostState.showSnackbar()
is suspending and ensures only one snackbar is shown at a time.
suspend fun showSnackbar(
message: String,
actionLabel: String? = null,
duration: SnackbarDuration = SnackbarDuration.Short,
): SnackbarResult =
mutex.withLock {
try {
return suspendCancellableCoroutine { continuation ->
currentSnackbarData =
SnackbarDataImpl(message, actionLabel, duration, continuation)
}
} finally {
currentSnackbarData = null
}
}
-
Mutex.withLock { ... }
ensures only one caller enters the block at a time; other callers suspend and will continue in FIFO order. -
suspendCancellableCoroutine { continuation -> ... }
: suspends the caller and hands you a Continuation. Later, when the snackbar is dismissed or its action is pressed, the implementation callscontinuation.resume(result)
to wake the suspended caller with a SnackbarResult. If the job is cancelled meanwhile, the continuation is cancelled promptly.
Combining these, we have a queue behaviour allowing single operation (in this case snackbar) to be shown on the screen. This pairing feels like a queue because the first call must complete before the next call proceeds. However, it’s important this is not same as java.util.Queue
we have seen on Java. (link)
Top comments (0)