Hello, i have a question regarding the use of runB...
# coroutines
t
Hello, i have a question regarding the use of runBlocking in production code and what is causing my intermittent failure in the following code snippet
private fun something(things: List<Thing>): List<OtherThing> {
val otherThings = mutableListOf<OtherThing>()
runBlocking(<http://Dispatchers.IO|Dispatchers.IO>) {
things.map {
async {
val whatEver = somethingElse(it)
if (whatEver) otherThings.add(process(it))
}
}.awaitAll()
}
return otherThings.take(someAmount.toInt())
}
fun process(thing: Thing): OtherThing {
return thing.copy(data = thing.data.replace(Regex(NON_LETTER_PATTERN), ""))
}
when the code runs as above I see intermittent test failures in my asserts when i refactor
runBlocking(<http://Dispatchers.IO|Dispatchers.IO>) {}
to
runBlocking {}
i never see assert failures
im sure i remember seeing a comment that
xxx.map ( async {} )
has a subtle bug however i cannot find that now if i shouldnt be using runBlocking in production code what are my alternatives?
s
I would guess that it could be an issue due to concurrent modification of the
otherThings
list
<http://Dispatchers.IO|Dispatchers.IO>
has multiple threads so the async tasks could run in parallel, whereas with just
runBlocking
it would run in a single threaded event loop
t
yes, i believe that is the root cause maybe i could fix that by
<http://Dispatchers.IO|Dispatchers.IO>.limitedParallelism(1)
however i realy do not like the use of
runBlocking
s
The advice against
runBlocking
is most important if this code is already running inside a coroutine. In that case, you should make
something
a suspend function, and replace
runBlocking
with
coroutineScope { ... }
.
👍 1
If there's no existing coroutines,
runBlocking
may be an okay choice