Skip to content

Instantly share code, notes, and snippets.

@objcode
Created March 10, 2019 23:31
Show Gist options
  • Save objcode/de62afbf8c4be42bde28f57c929d2507 to your computer and use it in GitHub Desktop.
Save objcode/de62afbf8c4be42bde28f57c929d2507 to your computer and use it in GitHub Desktop.
package com.example.android.gdgfinder.libs
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
class RequestLimiter<R>(scope: CoroutineScope) {
val requestChannel = Channel<Pair<suspend () -> R, CompletableDeferred<R>>>()
init {
scope.launch {
// don't know thread we're running on?? -- does it matter?
for ((request, resultDeferred) in requestChannel) {
try {
resultDeferred.complete(request())
} catch (exception: Throwable) {
resultDeferred.completeExceptionally(exception)
}
}
}
}
suspend fun doRequest(block: suspend () -> R): R {
val result = CompletableDeferred<R>()
requestChannel.send(block to result)
return result.await()
}
}
fun <R> CoroutineScope.singleRequestLimiter() = RequestLimiter<R>(this)
val RepositoryScope = CoroutineScope(Dispatchers.Main)
// usage
val requestLimiter = RepositoryScope.singleRequestLimiter<Int>()
suspend fun useIt() = requestLimiter.doRequest {
1 // for very async values of 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment