-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IO thread pool for blocking calls #79
Comments
Java 6 has
We can tune However we should consider that specific use case should create a fine tuned IO executor without using the global one. |
We need to make sure that there is no confusion in difference between |
Kotlin can provide an explicit annotation (like @DslMarker) to avoid invocation from coroutine. So we can rename the function to
|
Using the code:
I/O thread should be interrupted? |
We should not do interruption by default. It is dangerous. But we definitely need some easy way to adapt an interruptible blocking API (when we are sure it plays well with interrupts) to coroutines. I don't know yet what is going to be the best solution for this. This is also related to #57 |
@fvasco W.r.t to |
IMHO the name is misleading. When I see |
Hh... the assumption was that the code inside |
@elizarov Why not use |
because it's not blocking? and rxjava already has Schedulers.io() which does the same thing |
I would call it IOPool (similar to common pool) with the ability to give it number of concurrent operations as parameter. |
BTW, why do we need to call it |
A bit unrelated question. How a coroutine integrates with locks?
this might looks reasonable, but putting this line in actors, in thousand of actors can easily drain the pool or, on other hand, it can create thousand of threads. Currently I can't figure how integrate coroutine to synchronized block, locks, etc... Without a golden rule to execute any kind of blocking code I consider really helpful highlight the IO nature of this dispatcher. |
On the naming: we don't have to have |
@fvasco Good point. You could use "IO" pool for integration with blocking queues etc. I mean, if you have to integrate with somebody else's |
Here is a fresh idea that was pointed to by Raul Raja at public Slack. It suffices to have a single CPU-optimized dispatcher is we also provide Scala-like |
Please correct me if i am wrong, |
Let me clarify. Here is a problem we have: We need to be able to do both CPU-bound tasks and IO/blocking tasks with coroutines. The original proposal (this github issue) was to achieve this via a dedicated IO-tuned dispatcher, so you'd separate these two use-cases by choosing an appropriate dispatcher:
The alternative idea is to borrow Scala's approach: instead of two separate dispatchers let's have a single dispatcher (let's call it
What I particularly like about it, is that with this approach is makes sense to truly make this
|
it looks like a good idea to me.
But when I use IO, I usually use the thread pools to limit the number of
concurrent io operations I do in parallel. is there a way to put such a
limit with that suggestion?
…On Mon, Sep 18, 2017 at 11:24 AM, Roman Elizarov ***@***.***> wrote:
Let me clarify. Here is a problem we have: We need to be able to do both
CPU-bound tasks and IO/blocking tasks with coroutines. The original
proposal (this github issue) was to achieve this via a dedicated IO-tuned
dispatcher, so you'd segment these two use-cases by choosing an appropriate
dispatcher:
launch(CommonPool) { ... cpu-bound code ... }
launch(IO) { ... blocking IO code ... }
The alternative idea is to borrow Scala's approach. Instead of two
separate dispatcher let's have a single dispatcher (let's call it
DefaultDispatcher) and use it like this:
launch(DefaultDispatcher) { ... cpu-bound code ... }
launch(DefaultDispatcher) { blocking { ... blocking IO code ... } }
What I particularly like about it, is that with this approach is makes
sense to truly make this DefaultDispatcher a global default for all
coroutine builders and just write:
launch { ... cpu-bound code ... }
launch { blocking { ... blocking IO code ... } }
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#79 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACj0QanQhfoatPqQGbKyDnkVWhL4iJPbks5sjijHgaJpZM4OODA2>
.
|
I agree but it does not look so fresh, |
@fvasco It finally clicked into my mind when I understood how it shall interface with a scheduler. The difference from PR #83 is that it should not require a switch of context at all if the scheduler that currently runs coroutine natively supports blocking operations itself and counts the number of ongoing blocking operations to make decisions on creating new threads. |
@oshai You can always create thread-number limited context for your blocking ops. It is very good choice for people striving for best control. For example, if you are going JDBC and you want to limit your code to at most The idea behind |
@fvasco The other difference is that this
This way, you will be able to use it anywhere in your blocking code, regardless of whether you are going to run it from coroutine or not, and it will have the effect of signaling to the IO-aware coroutine scheduler when it is being use from coroutines. However, the other implementation option is to declare it as |
UPDATE on the current design thinking around this issue:
Open questions:
|
|
What about |
Or |
I like |
It is also possible to solve this debate renaming the
I consider usefull a dedicated builder, expecialling to indicate the synchoronous/blocking nature of invoked functions. |
Renaming As for the naming of the context please keep in mind #261. All the contexts will be backed by the same shared pool, so I don't think it is appropriate to use Let me also link a related discussion on the naming of dispatchers: #41. I'm not convinced that we should isolate names of the dispatchers into a separate named, but I'm also not firmly convinced that they should be top-level. |
Personally I consider the A coroutine context appears more rich than a single coroutine dispatcher, so use Instead, defining
leads me to consider
Unfortunately I haven't solved this issue, I am sorry. |
Now when we merged experimental coroutines dispatcher we can deliver |
I'm a bit confused as to what to expect for the future of kotlinx.coroutines default/recommended dispatchers. Will we have to continue running I/O separate from CPU-bound tasks like it's currently done with |
The expected future looks like this. There going to be only a single pool of threads in addition to
|
Are you considered:
and later in #261 ? |
* Dispatchers.Default — a default dispatcher for background asynchronous tasks (currently backed by FJP commonPool, a new dispatcher in the future). * Dispatchers.IO — a dispatcher for blocking background operations (#79). * Dispatchers.Main — a dispatcher for Android Main Thread (#533). * Dispatchers.Swing — a dispatcher for Swing Event Dispatch Thread. * Dispatchers.JavaFx — a dispatcher for JavaFx Application Thread. * Old dispatchers are deprecated, CommonPool is deprecated, too. * awaitPulse() in JavaFx and awaitFrame() in Android are top-level funs. * Introduced HandlerDispatcher, SwingDispatcher, and JavaFxDispatcher types in the corresponding UI modules for type-safety and future extensions Fixes #41
* Dispatchers.Default — a default dispatcher for background asynchronous tasks (currently backed by FJP commonPool, a new dispatcher in the future). * Dispatchers.IO — a dispatcher for blocking background operations (#79). * Dispatchers.Main — a dispatcher for Android Main Thread (#533). * Dispatchers.Swing — a dispatcher for Swing Event Dispatch Thread. * Dispatchers.JavaFx — a dispatcher for JavaFx Application Thread. * Old dispatchers are deprecated, CommonPool is deprecated, too. * awaitPulse() in JavaFx and awaitFrame() in Android are top-level funs. * Introduced HandlerDispatcher, SwingDispatcher, and JavaFxDispatcher types in the corresponding UI modules for type-safety and future extensions Fixes #41 Fixes #533
* Dispatchers.Default — a default dispatcher for background asynchronous tasks (currently backed by FJP commonPool, a new dispatcher in the future). * Dispatchers.IO — a dispatcher for blocking background operations (#79). * Dispatchers.Main — a dispatcher for Android Main Thread (#533). * Dispatchers.Swing — a dispatcher for Swing Event Dispatch Thread. * Dispatchers.JavaFx — a dispatcher for JavaFx Application Thread. * Old dispatchers are deprecated, CommonPool is deprecated, too. * awaitPulse() in JavaFx and awaitFrame() in Android are top-level funs. * Introduced HandlerDispatcher, SwingDispatcher, and JavaFxDispatcher types in the corresponding UI modules for type-safety and future extensions Fixes #41 Fixes #533
* Dispatchers.Default — a default dispatcher for background asynchronous tasks (currently backed by FJP commonPool, a new dispatcher in the future). * Dispatchers.IO — a dispatcher for blocking background operations (#79). * Dispatchers.Main — a dispatcher for Android Main Thread (#533). * Dispatchers.Swing — a dispatcher for Swing Event Dispatch Thread. * Dispatchers.JavaFx — a dispatcher for JavaFx Application Thread. * Old dispatchers are deprecated, CommonPool is deprecated, too. * awaitPulse() in JavaFx and awaitFrame() in Android are top-level funs. * Introduced HandlerDispatcher, SwingDispatcher, and JavaFxDispatcher types in the corresponding UI modules for type-safety and future extensions Fixes #41 Fixes #533
@elizarov What's the state of mind on this issue? IMHO of all the names suggested above, |
We need some kind of
IO
dispatcher inkotlinx.coroutines
that will be optimized for offloading of blocking calls and will be backed by an unbounded thread-pool that is smart enough to create new threads only when needed and to shut them down on timeout. The goal is that you could always wrap blocking IO call inwithContext(IO) { ... }
(UPDATED: it was formerly namedrun(IO)
) and be sure that you will not run into the problem of having not enough threads in your pool. However, it will be up to the user to control the maximal number of concurrent operations via some other means.It will be somewhat conceptually similar to
newThread()
scheduler in Rx, but it will be also designed to be used whereio()
scheduler in Rx is used.The text was updated successfully, but these errors were encountered: