I am translating our current application from Java to Kotlin and I came upon this problem.
The java implementation used to use threads to transfer data from the server.
It would create about 100 different threads that would request data, but from what I have seen no more than 4 would run at a time, the others would wait for a thread to finish before starting.
When translating it to Kotlin I used Coroutines
This creates a problem because apparently the server can't handle 100 requests actually being sent.
All coroutines are launched in the same scope , so it's something like this:
//this is a custom scope that launches on Dispatchers.IO + a job that I can use to cancel everything
transferScope.launch {
//loadData is a suspending function that returns true/false
val futures = mDownloadJobs.map{ async { it.loadData() } }
val responses = futures.awaitAll()
//check that everything in responses is true etc....
}
Is there a way to make the specific transferScope to allow only up to 5 coroutines at a time and then when one finishes let a different one run? (I do not care about the order)
If it can't be done through the scope, is there a different way this can be achieved?
A coroutine is executed inside a thread. One thread can have many coroutines inside it, but as already mentioned, only one instruction can be executed in a thread at a given time.
There are basically 3 scopes in Kotlin coroutines: Global Scope. LifeCycle Scope. ViewModel Scope.
Definition of runBlocking() functionRuns a new coroutine and blocks the current thread interruptible until its completion. This function should not be used from a coroutine. It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in main functions and in tests.
Answer: a. You should not use them for any foreground task.
Require each coroutine to acquire a Kotlin Semaphore
permit from a total of 5 permits before making a request.
Something like this:
import kotlinx.coroutines.sync.Semaphore
val requestSemaphore = Semaphore(5)
val futures = mDownloadJobs.map {
async {
// Will limit number of concurrent requests to 5
requestSemaphore.withPermit {
it.loadData()
}
}
}
val responses = futures.awaitAll()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With