Created
August 1, 2018 05:29
-
-
Save maxpert/1be77c565d374f47980bfbe0f6d5e744 to your computer and use it in GitHub Desktop.
Kotlin Coroutine Debouncer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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