Skip to content

Allow plugging into CoroutineScheduler to know when it's about to run CPU or Blocking work #4506

@LouisCAD

Description

@LouisCAD

Hello! Here's a feature request, with API proposals:

Use case

I'd like to track down misuse of Dispatchers.Default and Dispatchers.IO (including derivates with limitedParallelism(…) in an Android app.

Android provides a wonderful API for that: StrictMode.ThreadPolicy.

It runs at the thread level, and knows nothing about kotlinx.coroutines.

What I'd like is to have a cpuBoundWorkThreadPolicy and a blockingIoThreadPolicy, that I'd set back and forth on the threads used by CoroutineScheduler that powers Dispatchers.Default, Dispatchers.IO and its limitedParallelism(…) derivatives.

That would allow setting a policy that reports blocking I/O done on Dispatchers.Default, and long custom calls (most likely CPU bound) done on Dispatchers.IO.

It'd also be nice to be able to have ability to collect live metrics on how long dispatches are taking on a given dispatcher, to identify if the tasks are broken down enough, or if they lack cooperativeness and should yield more, but that'd probably need a more involved API.

Injecting custom wrapping dispatchers that perform the measures everywhere is not an option because it affects API stability, and doesn't work for compiled libraries. I'm looking for 100% of a solution.

The Shape of the API

If an Android specific API was done (kinda like has been done for awaitFrame() and HandlerDispatcher), here's a few examples on how it could look like:

Dispatchers.setStrictModeThreadPolicies(cpuBoundWorkPolicy, blockingIoWorkPolicy)
Dispatchers.setStrictModeThreadPolicies(mainThreadPolicy, cpuBoundWorkPolicy, blockingIoWorkPolicy)
Dispatchers.IO.threadPolicy = blockingIoWorkPolicy
Dispatchers.Default.threadPolicy = cpuBoundWorkPolicy

Here are platform agnostic versions:

fun interface CoroutinesTaskTypeChangedListener {
    fun onThreadTaskTypeChanged(newTaskType: TaskType)
}

Dispatchers.addTaskTypeChangeHook { taskType ->
    when (taskType) {
        TaskType.CpuWork -> StrictMode.setThreadPolicy(cpuWorkThreadPolicy)
        TaskType.BlockingWork -> StrictMode.setThreadPolicy(blockingWorkThreadPolicy)
    }
}

What do you think about those ideas?

Have a nice day!

Louis CAD

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions