-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
The documentation for tokio_threadpool::blocking
assumes more understanding of Tokio than we can rely on
#618
Comments
Do you have any rough thoughts on how this could be worded? I'm thinking along the lines of like... explaining a task vs a future in the sense of a task being a future or future chain, and how a blocking operation within the chain/task stalls the whole thing. It feels pretty self-explanatory -- if you have something in a future that blocks, everything that depends on that future also blocks -- but I also see what you're saying about it being non-obvious. I'm not sure that the people who think of these things as "obvious" are equipped to come up with the best explanation for it, if that makes sense. Having that outside perspective, even if it's just a seed of a sentence, would help a lot. |
This relates to #589 and #588. I agree that there is a problem here. The There should be a general purpose blocking strategy that has the behavior you described. This would have to work by moving the blocking operation to a separate thread. Issue #588 represents this work. |
As background, the naïve view is that a single future is the scheduling atom. Tasks will "steal" notified futures from other tasks if the other task is busy, just as threads "steal" waiting tasks from other threads if other threads are busy. Thus, something along the lines of "The resulting future will block the entire task it is running on until the blocking activity is complete - other futures on the same task will not execute until the blocking activity returns to the caller. If this is not desired, you will need to spawn a new task to run the blocking activity". Basically, make it clear that you will not see parallel execution if you have a blocking future. |
@farnz I was looking to lift a blocking IO library into a Tokio server, and ended up following a similar pattern to your utility functions. Thank you for sharing! One question for you: Because all the closures end up being |
@blakesmith Worth noting that I don't end up wrapping all my captured variables in {
let thing = thing.clone(); // Repeated as needed
move || {
let data = thing.as_data();
blocking_operation(data)
}
} The reason |
@farnz Ah, that makes sense, thanks for explaining, especially the semantics of Cheers, and thanks again! |
This is connected to @jsgf's issue #617, which demonstrates this confusion nicely.
The documentation for
tokio_threadpool::blocking
in version 0.1.6 states:A naïve reading suggests that if you have a
blocking
futureselect
ing with another future, both futures will run concurrently. This is not true; the threadpool works at the level of tasks, not futures, and all thatblocking
actually does is tell the scheduler two things:blocking
code indefinitely.However, both Jeremy and I, plus a third co-worker, ended up confused by this and expected that just the
blocking
section would run on a new thread, while other futures would continue to run on the current thread.In code terms, we have the following in a utility library:
Our naïve expectation is that:
would be a future that would return the result of
other_future
or return after 1,500 seconds, whichever came first.The reality is that the thread you run this future on will be blocked for 1,500 seconds to let the
blocking
block run on the thread, and thenother_future
will be allowed to run. We have to use the full machinery inasynchronize
to get the blocking thread onto its own task, at which point the two futures can run concurrently.Can we improve the documentation to make it clear that
blocking
does not create a fresh task, and thus that the worker that runs the blocking code section will not execute other futures even if they're ready to work? The example includesspawn
, but it's not very obvious that notspawning
onto a new task may have unexpected results.The text was updated successfully, but these errors were encountered: