Blocking threads, suspending coroutines
Roman Elizarov

Interesting article! But what is the convention if I have chains of suspending function calls? For example in an application that follows the Clean Architecture paradigm, I have a Repository that calls a Remote that calls an Api.

class Repository(private val remote: Remote) {
suspend fun fetchData(): Data = remote.fetchData()
class Remote(private val api: Api) {
suspend fun fetchData(): Data = api.fetchData()
class Api() {
suspend fun fetchData(): Data = withContext(Dispatchers.IO) {
// Actual I/O operation

Should all calls be wrapped in withContext()? The Repository doesn’t and shouldn’t know that an I/O operation is performed. After all the data could also be fetched from memory. So should I use Dispatchers.Default for Repository and Remote? What if I have multiple, chained withContext() calls with same or different dispatchers? Does this impact the performance somehow?