https://kotlinlang.org logo
#coroutines
Title
# coroutines
r

rrva

09/07/2020, 10:47 AM
I have a wrapper function to limit concurrent calls to a service looking like this:
Copy code
private val concurrentRequests = Semaphore(50)

private suspend fun <T> requestWithLimit(block: suspend () -> T): T {
    try {
        withTimeout(10) {
            concurrentRequests.acquire()
        }
    } catch (e: Exception) {
        throw RuntimeException("Overloaded", e)
    }
    try {
        return block()
    } finally {
        concurrentRequests.release()
    }
}
I usually call io.ktor.client.HttpClient.request inside block(). If I want to write it as an extension function on io.ktor.client.HttpClient (just to make the call site a bit cleaner), how would I define it? It seems that the extension function cannot access the variable
concurrentRequests
w

wasyl

09/07/2020, 10:58 AM
Making
requestWithLimit
shouldn’t change how you access
concurrentRequests
. This does seem to work for me:
Copy code
suspend fun <T> HttpClient.requestWithLimit(block: suspend HttpClient.() -> T): T
Full code:
Copy code
abstract class HttpClient {

    abstract val request: Any
}

val concurrentRequests = Semaphore(50)
private suspend fun <T> HttpClient.requestWithLimit(block: suspend HttpClient.() -> T): T {
    try {
        withTimeout(10) {
            concurrentRequests.acquire()
        }
    } catch (e: Exception) {
        throw RuntimeException("Overloaded", e)
    }
    try {
        return block()
    } finally {
        concurrentRequests.release()
    }
}

suspend fun usage(httpClient: HttpClient) {
    httpClient.requestWithLimit {
        println("Doing something with $request")
    }
}
2 Views