Support "worker pool" pattern in actor builder and other related operators
See original GitHub issueactor
builder should natively support “worker pool” pattern via an additional optional parameter ~parallelism~ concurrency
that defaults to 1
, so that to you if you have a list of of some requests, then can be all processed concurrently with a specified limited concurrency with a simple code like this:
val reqs: List<Request> = ...
val workers = actor(concurrency = n) {
for (it in channel) processeRequest(it)
}
This particular pattern seems to be quite common, with requests being stored in either a list of requests of receive from some other channel, so the proposal is to add concurrency to map
, and cosumeEach
, too, to be able to write something like:
incomingRequests.consumeEach(concurrency = n) { processRequest(it) }
UPDATE: We will consistently call it concurrency
here. We can have dozens of concurrent coroutines which run on a single CPU core. We will reserve the name parallelism
to denote limits on the number of CPU cores that are used.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:37
- Comments:13 (7 by maintainers)
Top GitHub Comments
I want to bump this issue. This pattern is so often, I see questions about implementation at least each week on Kotlin Slack
#coroutines
channel also all fast ad-hoc implementations often have problems (a similar problem we had before awaitAll extensions, when simple extension functions just usemap { it.await() }
which leak coroutines in case of error)This pattern is common enough even outside of actors (e.g. make a lot of web requests, but only have 10 going at a time) that it seems like it might be worth having a separate api for launching
n
amount of coroutines, and use that here, rather than vise versa. At the very least there should be something similar forproduce
.Something like:
Only 10
doThing
s would be executing at any given time.Where any
launch
es would be redirected to either a worker thread, forced to be lazy and started once there is room, or just have the block held until there is room, then launched.