Is there a notion of priority with coroutines? I'd...
# coroutines
d
Is there a notion of priority with coroutines? I'd like to do some job in background but I'd like it to be executed ASAP, before other queued & less important jobs
p
You can pass
CoroutineStart.UNDISPATCHED
to start execution immediately (until first suspension point)
Though this doesn't set any priority per se
d
This is not what I'm looking for. It's even worse, it will execute the code in the current context, not the one I specified
e
You can create a separate dispatcher with a thread pool of high-priority threads or simply the one you don’t use often (so there is not much work in this dispatcher)
g
But thread priorities doesn’t work on Android, ths system just ignores thread priority (excluding special ones, like audio thread etc)
e
Thanks. I did not know that. Btw, what is the use-case for coroutines with priorities?
d
Really? In Java I set priorities for my threadpool, I've been fooled all this time? My use case is list updates (priority) vs list items images loading potentially flooding the CommonPool
e
For this use-case just use a different dispatchers for different tasks
d
That's what I do for now, I'll stick to it. Thanks
g
In Java I set priorities for my threadpool, I’ve been fooled all this time
If you do that on Android yes, it’s useless
My use case is list updates (priority) vs list items images loading potentially flooding the CommonPool
But how this related to CommonPool? I just don’t see how you can achieve this with different dispatchers, bottleneck is network, not CPU, so all those thread priorities are useless for this case. Also, if you use something like okhttp with async API it has own thread pool under the hood for “non-blocking” requests with own strategy (limit amount of parallel requests per host)
d
It's loading images from local storage. list updates causes potentially long computation. Dozens of images loading => CommonPool I'm fine with a specialized dispatcher.
g
It’s loading images from local storage
so it’s blocking IO operation and shouldn’t be done in CommonPool Until we have non-blocking IO on Android, special IO dispatcher is the only option
in case of work with disc CPU and thread priority is also not a problem, bottleneck is IO speed. So both of your operations: network and disk IO are not fight for resources if you give them enough threads
d
I know for I/O… I'm considering doing the opposite now. Special context for I/O, then CommonPool for updates calculation will be fine.
g
if those calculation are not very heave, because for heavy computations make sense to use some other dispatcher bounded by CPU count, because you don’t want to lock threads in CommonPoool
so you need analog of RxJava
<http://Schedulers.io|Schedulers.io>()
for network and IO and
Schedulers.computation()
for computation
d
Computation shouldn't take more than a second, I feel it's OK to do it in
CommonPool
g
On practice you probably right, but it’s still chance that you lock all non-blocking corroutine operations
image that you run your code on device with 2 cores, it means that CommonPool has only 1 thread and you lock it with your computation, so all the coroutines, even non-blocking, will wait for your computations
d
I see your point. But with only 1 core available, event with a special dispatcher, CPU will queue jobs
Here it is
DiffUtil.calculateDiff
, in my becnhmarks, the most I got was around 130ms with a Gaxaxy S1 on a 1300+ items list
e
Scheduling between threads is preemptive. With different dispatcher you can be sure that the jobs you submit to your “high priority” dispatcher will have not have to wait too long until they can execute.
g
Exactly what Roman said, context switch in your case is not the biggest problem, especially for IO
w
So even though there is a very limited number of threads, it's better to use a special dispatcher for IO?
Is this also the case when making sure to use
yield()
properly? For instance, every database/io call, I run in a block that always yields after the IO operation.
g
limited number of threads, it’s better to use a special dispatcher for IO
limited number of threads? What do you mean? If IO is blocking than better to use special dispatcher that would be safe to block (at least you expect that this dispatcher can be blocked) There is proposal to change threading strategy and use single pool of threads for different dispatchers: https://github.com/Kotlin/kotlinx.coroutines/issues/261
w
Let's take an Android example of 1 available thread. If I have an operation that takes 1000ms, it's going to block the thread regardless of dispatcher, because there is only 1 thread. So then, does it really matter if I run this blocking operation on a different dispatcher?
Oh, I see, if this is IO related, the dispatcher can move off the thread while waiting for the IO to return back.
g
As Roman said, thread scheduling is preemptive, so even if you have 1 core it doesn’t mean that you cannot run a few more threads, for IO operations it’s just fine, and even for computations, if you run 1000ms computation it doesn’t mean that your UI will freeze, OS scheduler will handle this, of course computation time will be more than 1000ms, but it also allows other threads to run and finish their job
👍 1
d
Thanks Roman and Andrey, I get the logic now. And focusing on coroutines, I quite forgot thread scheduling 🙂
795 Views