Skip to content

Instantly share code, notes, and snippets.

@maxpert
Created August 1, 2018 05:29
Show Gist options
  • Save maxpert/1be77c565d374f47980bfbe0f6d5e744 to your computer and use it in GitHub Desktop.
Save maxpert/1be77c565d374f47980bfbe0f6d5e744 to your computer and use it in GitHub Desktop.
Kotlin Coroutine Debouncer
class CoroutineDebouncer<K, V> constructor(
private val pendingBoard: ConcurrentMap<K, Deferred<V?>>
) {
/**
* Debounce given a `task` based upon given `id`. This prevents jobs with same IDs run in parallel.
* For subsequent callers get Deferred<V> of first (winning) coroutine.
* Once Deferred<V> completes it is remove from the board.
*
* @param id for uniquely identifying a task
* @param context under which given coroutine will be executed
* @param task to execute if there isn't already a task with given `id`
*
* @return Deferred<V> created by scheduled `task` or an existing Deferred<V> from previous coroutines
*/
suspend fun debounce(id: K, context: CoroutineContext, task: suspend () -> V?): Deferred<V?> {
return pendingBoard.computeIfAbsent(id) {
async (context, start = CoroutineStart.LAZY) {
try{
task()
} finally {
pendingBoard.remove(id)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment