Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to increase Kotlin coroutines Dispatchers.IO size on Android?

Coroutines Dispatchers.IO context is limited to 64 threads. That's not enough to reliably interface with blocking code in highly-concurrent system.

Documentation states that:

Additional threads in this pool are created and are shutdown on demand. The number of threads used by this dispatcher is limited by the value of “kotlinx.coroutines.io.parallelism” (IO_PARALLELISM_PROPERTY_NAME) system property. It defaults to the limit of 64 threads or the number of cores (whichever is larger).

I want to change kotlinx.coroutines.io.parallelism system property to something else. However, if I just do this:

adb shell "setprop kotlinx.coroutines.io.parallelism 1000"

then I get the following result:

setprop: failed to set property 'kotlinx.coroutines.io.parallelism' to '1000'

Furthermore, if I want to ship my app, then I'll need to change this property on users' devices as well, right? Otherwise the app won't work. However, even assuming that it's possible, as far as I understand, all apps that change this property will override the setting for one another. This doesn't sound like a reliable mode of operation.

So, I have three questions in this context:

  1. Is the property implied in documentation is indeed the "system property" that I tried to change?
  2. How to change this property on non-rooted device for all users of my app?
  3. Is there better alternative?

P.S. I know that if I'd only use coroutines, without blocking code, this wouldn't be a problem (probably). But let's just assume that I need to use blocking calls (e.g. legacy Java code).

like image 679
Vasiliy Avatar asked Oct 21 '19 15:10

Vasiliy


People also ask

What is Dispatchers IO in coroutine?

Dispatchers.IO is designed to be used when we block threads with I/O operations, for instance when we read/write files, use Android shared preferences, or call blocking functions. The code below takes around 1 second because Dispatchers.IO allows more than 50 active threads at the same time.

What is dispatcher in Kotlin coroutines Android?

Kotlin coroutines use dispatchers to determine which threads are used for coroutine execution. To run code outside of the main thread, you can tell Kotlin coroutines to perform work on either the Default or IO dispatcher. In Kotlin, all coroutines must run in a dispatcher, even when they're running on the main thread.

Why Kotlin coroutines are lightweight?

Lightweight: You can run many coroutines on a single thread due to support for suspension, which doesn't block the thread where the coroutine is running. Suspending saves memory over blocking while supporting many concurrent operations. Fewer memory leaks: Use structured concurrency to run operations within a scope.

What is CoroutineScope in Kotlin?

Kotlin coroutines provide an API that enables you to write asynchronous code. With Kotlin coroutines, you can define a CoroutineScope , which helps you to manage when your coroutines should run. Each asynchronous operation runs within a particular scope.


3 Answers

IO_PARALLELISM_PROPERTY_NAME does not refer to an Android system property, but to a Java system property. Just add this code early in your app, e.g. first in your Application.onCreate(), to change it to 1000:

import static kotlinx.coroutines.DispatchersKt.IO_PARALLELISM_PROPERTY_NAME;

System.setProperty(IO_PARALLELISM_PROPERTY_NAME, Integer.toString(1000));

This does not have to be done on a per-device basis with root or anything like that. It will work everywhere, since it is regular app code using regular app APIs.

As long as you do this before you use Dispatchers.IO for the first time, your property change will be applied.

like image 175
Enselic Avatar answered Oct 14 '22 05:10

Enselic


You can create your own dispatcher with any number of threads, like so

val dispatcher = Executors.newFixedThreadPool(128).asCoroutineDispatcher()
like image 12
Francesc Avatar answered Oct 14 '22 05:10

Francesc


With kotlinx-coroutines-1.6.0 you can limit the threads that are used for Dispatchers by using "limitedParallelism" method.

Example:

// 100 threads for MySQL connection
val myMysqlDbDispatcher = Dispatchers.IO.limitedParallelism(100)
// 60 threads for MongoDB connection
val myMongoDbDispatcher = Dispatchers.IO.limitedParallelism(60)

Release note: https://blog.jetbrains.com/kotlin/2021/12/introducing-kotlinx-coroutines-1-6-0/#dispatcher-views-api

like image 2
Mehmet Sezer Avatar answered Oct 14 '22 05:10

Mehmet Sezer