I’m developing an app reading data from a network real-time service and rendering those data in the view, as soon as possible and without delays. Delays like over 200-300 msec are not tolerated. It’s okay if some messages get lost but no delays.
My implementation is the following:
- a thread loop receiving messages from backend and writing the value of a data layer StateFlow;
- a StateFlow for viewModel observing the data layer StateFlow above;
- the ViewModel StateFlow is collected via a
collectAsStateWithLifecycle
in the Screen.
The context for the first two operations is Dispatchers.IO
as they are async operations.
The problem is: Dispatchers.IO
threads are background ones and get less CPU resources than the main ones. This results in less capacity of controlling max delay in getting you the results.
Searching around, it looks like it’s possible to create background thread pools with priority. And as far as I’ve understood, this could mean the possibility to prioritize some thread contexts in order to get the results ASAP. I’ve found this lib which helps creating those. So now the network receiver code looks like this:
suspend operator fun invoke() {
CoroutineScope(PriorityDispatcher.immediate()).launch {
var delivery: Delivery?
while (isActive) {
val receivedMessage = receive()
_receiverState.value = receivedMessage
}
}
}
when receive()
runs in the same context. Before this change, it was like withContext(Dispatchers.IO)
Obviously, for less prioritizing tasks, I’m using CoroutineScope(PriorityDispatcher.low())
. I’m still in the process of testing if this refactoring improved performances.
Do you think this is a good approach? Is this API an equivalent of launching on Dispatchers.IO/Dispatchers.Default
but adding the possibility of prioritizing some urgent tasks? If not, is there any way to do?
Thanks a lot in advance