-
Notifications
You must be signed in to change notification settings - Fork 20
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
[Discussion] A more ergonomic way to deal with 'blocking' futures #19
Comments
Is there anything I can do to help this along @taiki-e ? |
I don't have a strong opinion on this. However, bounded thread pools are not necessarily suitable for this case (see tokio-rs/tokio#3717 (comment) for more). |
Thanks for your reply, this sounds like a PR would be feasible to make using Maybe there can be extra-documentation to elaborate on the potential for deadlocks if there are complex inter-dependencies. |
I think this is not a good idea to direct pass a Future to the threadpool, and it is very easy to cause "bugs" in this usage. For example: blocking::spawn(// "maybe-blocking-future",
async move {
tokio::time::timeout(duration, async {}).await; // <- lost tokio context in threadpool
}
); Correct me if I misunstand your purpose. |
I think the above could be rewritten like the following… blocking::spawn(// "maybe-blocking-future"
tokio::time::timeout(duration, async {}) // <- lost tokio context in threadpool
); …wrapping in It may very well be that incorrect usage is possible especially with Or asked differently: Should
A function to spawn futures directly is what is indeed proposed here, and examples are made for how this would make |
Emm, the sample code is just for simplifing the real logic of my app which panics due to lost the tokio context (kills my whole afternoon to find out 🤣). Tokio may crash when running in the fresh new thread of threadpool. So it is quite "easy" to cause such a bug. |
I agree with the fact that this seems like an easy footgun to set off. If we're going to include this function, it should be very clearly marked as "know what you're doing". |
At
gitoxide
, a git implementation in Rust, most code is blocking as it relies heavily on operations which aren't available in 'real' async or are CPU bound.When implementing the server side or clients it becomes evident that due to the ecosystem one won't get around using
async
, and those usinggitoxide
for custom clients or on the server will have to integrate withasync
crates or framework.To get started with this and make what's there more flexible the client side is now available in
async
and a prototype client program exists to test the blocking/async interoperation from start to end.As all git repository interactions are blocking,
async
client code coming from thetransport
orprotocol
layers will have to call into that. The async parts must not block the executor, and parts of or the entire operation have to be unblocked.With the current API this looks like this:
Fully async portions remain async, but those who are at least partially blocking must be entirely unblocked. The need for
futures_lite::future::block_on
seems avoidable especially when looking at the underlying implementation which relies onExecutor::spawn(future)
receiving a future.If there was a function that takes a future, the code above could be simplified to the following:
I would love to hear your thoughts about this usecase, and if there is interest will be happy to contribute.
The text was updated successfully, but these errors were encountered: