What is a correct way to collect a flow using a ce...
# coroutines
s
What is a correct way to collect a flow using a certain dispatcher? For example, I have a code like this that needs to run on the Dispatchers.IO:
Copy code
summaryFlow().take(100).collect { summary ->
    fileWriter.write(Json.encodeToString(summary))
}
What is the correct way to do it? Should I use withContext inside of the lambda, or flowOn before it?
y
I believe you just surround the
collect
call itself in
withContext
👍 1
z
flowOn
will change the context in which everything upstream of the operator runs. • Surrounding the
collect
call with
withContext
will change the context in which the
collect
body runs, and may change the context upstream (but
flowOn
would override that). • Putting
withContext
inside the
collect
will only change the context that the actual
write
and
encodeToString
functions run in.
Generally it's best to only switch to the IO dispatcher for actual blocking IO call, so the best way would probably be:
Copy code
summaryFlow().take(100).collect { summary ->
  // This is CPU-bound work, so don't switch to IO yet.
  val encoded = Json.encodeToString(summary)

  // This is the blocking IO call.
  withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
    fileWriter.write(encoded)
  }
}
But in practice running the encode on the IO dispatcher is probably fine too
s
Got it, thanks for the explaination!