-
Notifications
You must be signed in to change notification settings - Fork 1.9k
DefaultDispatcher
- why is this the CommonPool?
#351
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
Comments
This is quite opinionated I think. In my opinion, if async { } // surprise! It is not asynchronous! Usually if you use And I'd like to precise that observable.subscribe { } // sychronous? asynchronous? Who knows? You have to check if `subscribeOn` and/or `observeOn` is present in the upstream.
channel.consumeEach { } // This is a suspending function always executed synchronously in the current context. |
Let me add some more insight here. I think you are looking for Rx-like cold-stream abstraction that does not start any background activity. We plan to provide that in the future. See #254. |
I would definitely be curious to hear more of this. Personally, I think the |
@ZakTaccardi I assume that you are looking for Rx-like streams (see #254). They will be not have any dispatcher by default and should match your expectations. However, for asynchronous background activities like On our other ideas see #410 |
Although this issue is closed, I would like to leave a piece of feedback on this. Our team builds a (production) web app with Spring a coroutines. Every time we bridge between Spring router and the rest of the code, we have to make sure to put On the other hand, every time someone needs a background task executed, the best practice is to create a separate thread pool with the needed settings and use it instead of In short, the current choice for |
I do a agree. But it doesn't change what I've said before: I think it would be a bit unnatural if
Sounds like some tasks were blocking the threads. In this case one should indeed not use the However. for computational tasks, |
@jcornaz nothing was really blocking, those task just happened to run when it was time for the timer coroutine to wake up. Also any task with higher priority could usurp the CPU and prevent coroutine switching.
My point is that when delegating to a thread pool, we always need to be explicit about that. Want to compute on IMO any thread pool with fixed number of threads is unfit to be the default dispatcher. |
This is a good point. I agree with it. Maybe the best would be to not have any default dispatcher at all? |
Having |
"useful" -> yes async { } // surprise! It is not asynchronous! I think forcing the user to be explicit could be nice. At least I'd prefer that than having |
We've lived with "you must be explicit" for a while, but we had to abandon this policy when we started to work on common code. You cannot require to be explicit in your common code, since JVM has threads and pool, but JS does no, so you cannot just go a write code that runs both on JS and JVM. We needed some default. What that default should be? It cannot be Now, with structured concurrency (#410) this should not be a big issue anymore. A default is used only when you do |
@elizarov May I ask which // here this function cannot suspend as it will be called by the UI framework in a blocking manner.
fun handleUiAction(event: ActionEvent) {
// what scope should I use here?
GlobalScope.launch { doSomeBackgroundWork() }
} |
@jcornaz |
@elizarov I've just read the papers on structured concurrency. Very cool! Did I get it right that now when I have a Spring class with request routing methods, I implement |
RxJava is synchronous by default. This behavior is awesome.
By default, coroutine builders like launch, async, produce, etc use the
CommonPool
. In RxJava, that's like automatically doing:Because it's a good pattern for testing and maintainability, I always inject my dispatchers.
Unfortunately, the
DefaultDispatcher
lets unfamiliar devs easily make the mistake of referring to the common pool. Even worse, they may not even understand what theCommonPool
is and just throw coroutines around and not understand in which dispatcher they run in.Why not make the default dispatcher
Unconfined
? That way devs will know that if they want to confine the coroutine to a particular context, they can pass the appropriate dispatcher.I think it's a bit confusing to have different coroutine builders refer to different dispatchers.
Note: I understand it's probably too late to change this behavior :(
The text was updated successfully, but these errors were encountered: