-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Implement AsyncRead for async response body: #482
Comments
+1. I've had a twitter exchange on this topic, seems not so hard: https://twitter.com/creepy_owlet/status/1210529708431073280. |
That's the (mostly untested) code I ended up with (for both directions): https://github.com/dtantsur/rust-openstack/blob/460be44dd2f9bfcc6d1277a7195e0c924e56ddf4/src/object_storage/utils.rs @seanmonstar does this ^^^ look at least remotely acceptable to you? |
The |
@seanmonstar the reason it gets (and will get) coming up is that without a sort of Read functionality, Body and Response are weird citizens in the IO world (even your own synchronous Response is Read!). Representing Response as a Stream is handy too, but it's a leaking abstraction exposing the way it's implemented. It's natural for hyper but quite surprising for a library aiming to be high-level. It also makes my life as a downstream library author harder because the problem is now pushed to my level. |
EDIT: The futures crate is intended to define a common vocabulary of runtime/reactor-agnostic primitives for crates like tokio to build on. However, the futures crate is not part of the Rust standard library, and so there is room for diagreement over what these primitives (like If your project does not depend on the tokio runtime/reactor specifically, you could potentially use async-std instead. Unlike tokio, async-std uses
If you want to stick with tokio as the runtime/reactor then here is one possible workaround:
EDIT EDIT: tokio now has a futures <--> tokio compatibility layer, see more in another comment below. |
thanks @benkay86 ! I'm trying to get a grip on doing concurrent downloads... do you mind taking a look at giving tips for how to go from your snippet to a proper concurrent-stream downloader? Here's what I have so far (including your code in a standalone fn): The idea is that
|
First off, I would recommend using the following for your type-erased generic error type. I explain the rationale in my blog post on Rust errors, but the short version is that you probably want to be able to send errors between threads.
In my code I am doing almost exactly the same thing in terms of parallel downloads using the
A few pearls here:
Suppose you continue to use
The pearls here:
Hope this helps get you started. |
excellent, thanks!! |
For anyone still following this, tokio now has a futures <--> tokio compatibility layer as of this PR. You can now use I've posted some examples including this one of how to use the compatibility layer. |
For anyone stumbling upon this, there is now also a fn response_to_async_read(resp: reqwest::Response) -> impl tokio::io::AsyncRead {
use futures::stream::TryStreamExt;
let stream = resp.bytes_stream().map_err(std::io::Error::other);
tokio_util::io::StreamReader::new(stream)
} |
reqwest::r#async::Decoder
does not currently implementtokio::io::AsyncRead
, which makes eg simple copying withtokio::io::copy
impossible.Would be nice to implement this.
The text was updated successfully, but these errors were encountered: