Kotlin / kotlinx.coroutines

Library support for Kotlin coroutines
Apache License 2.0
12.96k stars 1.84k forks source link

Dispatchers.setMain does not implement a correct Dispatchers.Main.immediate #3298

Open dkhalanskyjb opened 2 years ago

dkhalanskyjb commented 2 years ago

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-main-coroutine-dispatcher/immediate.html states that, if Dispatchers.Main.immediate is supported, it behaves like Dispatchers.Unconfined when already in the correct execution context; otherwise, it should throw UnsupportedOperationException. However, this is not the case for Dispatchers.setMain, which will just use the dispatcher itself for Dispatchers.Main.immediate, without preventing stack overflows or eager execution of coroutines.

This causes real problems in the test code. The main example is viewModelScope, a CoroutineScope that corresponds to a ViewScope, Android-specific storage of data for use in UI. Because of being UI-related, viewModelScope uses the UI thread by default, and to avoid unnecessary dispatches when working with a ViewModel from the main thread, it uses Dispatchers.Main.immediate.

Code that tests functions using viewModelScope is typically structured in a way that expects the dispatches to happen eagerly—corresponding to real-world behavior in the typical case—which necessitates the use of UnconfinedTestDispatcher in Dispatchers.setMain for such tests. However, this will lead to incorrect dispatching behavior for just Dispatchers.Main, which is supposed to behave like a StandardTestDispatcher.

The most straightforward idea is two-part:

1. Make StandardTestDispatcher a MainCoroutineDispatcher, confined to the thread and exposing a proper immediate.

Problems:

2. Throw UnsupportedOperationException for Dispatchers.Main.immediate for non-MainCoroutineDispatcher arguments to Dispatchers.setMain.

This is a breaking change.

joaoeudes7 commented 1 year ago

I'm using the temp solution: Dispatchers.setMain(Dispatchers.Unconfined), but waiting for the official resolution from the library