Created
May 13, 2021 15:01
-
-
Save iurysza/b27677f62bd90d5468b54c64f79449eb to your computer and use it in GitHub Desktop.
Generic throttleFirst behavior
This file contains hidden or 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
import com.movile.faster.sdk.util.DispatcherProvider | |
import kotlinx.coroutines.CoroutineScope | |
import kotlinx.coroutines.CoroutineStart | |
import kotlinx.coroutines.Deferred | |
import kotlinx.coroutines.async | |
import kotlinx.coroutines.delay | |
import kotlinx.coroutines.launch | |
import java.util.concurrent.ConcurrentHashMap | |
class CoroutineThrottler( | |
private val dispatchers: DispatcherProvider, | |
private val durationInMillis: Long = 300, | |
) { | |
private val deferredCache = ConcurrentHashMap<String, Any>() | |
/** | |
* This implements the [throttleFirst](http://reactivex.io/documentation/operators/images/throttleFirst.png) | |
* behavior for a given function. | |
* This mechanism uses the provided key to identify the [[block]] function and prevent the same block from running | |
* before the [[durationInMillis]] elapses. | |
* | |
* In short, this will effectively swallow all subsequent [[block]] for the [[durationInMillis]]. | |
* | |
* Note: the first call to the method starts running immediately | |
*/ | |
@Suppress("UNCHECKED_CAST") | |
fun <G : Any> throttleFirstAsync(key: String, block: suspend () -> G): Deferred<G> { | |
val deferredRequest = CoroutineScope(dispatchers.io()).async(start = CoroutineStart.LAZY) { block() } | |
val throttledRequest = deferredCache | |
.putIfAbsent(key, deferredRequest) | |
.let { it as? Deferred<G> } | |
?: deferredRequest | |
CoroutineScope(dispatchers.default()).launch { | |
delay(durationInMillis) | |
deferredCache.remove(key) | |
} | |
return throttledRequest | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment