Skip to content
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

Document hyper::body module with how to use different body types #3103

Open
Tracked by #2345
seanmonstar opened this issue Dec 28, 2022 · 4 comments
Open
Tracked by #2345

Document hyper::body module with how to use different body types #3103

seanmonstar opened this issue Dec 28, 2022 · 4 comments
Labels
A-body Area: body streaming. A-docs Area: documentation. E-medium Effort: medium. Some knowledge of how hyper internal works would be useful.

Comments

@seanmonstar
Copy link
Member

No description provided.

@seanmonstar seanmonstar added A-docs Area: documentation. E-medium Effort: medium. Some knowledge of how hyper internal works would be useful. A-body Area: body streaming. labels Dec 28, 2022
@IsaacCloos
Copy link
Contributor

IsaacCloos commented May 16, 2023

🙋🏻‍♂️

If this issue is available, I'd love to draft a solution.


Browsing through the body module I compiled this list of todos. Of course, please add more as you see fit:

  • Extend module overview with "top-level" perspective of available body types

    hyper/src/body/mod.rs

    Lines 1 to 15 in d894439

    //! Streaming bodies for Requests and Responses
    //!
    //! For both [Clients](crate::client) and [Servers](crate::server), requests and
    //! responses use streaming bodies, instead of complete buffering. This
    //! allows applications to not use memory they don't need, and allows exerting
    //! back-pressure on connections by only reading when asked.
    //!
    //! There are two pieces to this in hyper:
    //!
    //! - **The [`Body`](Body) trait** describes all possible bodies.
    //! hyper allows any body type that implements `Body`, allowing
    //! applications to have fine-grained control over their streaming.
    //! - **The [`Incoming`](Incoming) concrete type**, which is an implementation of
    //! `Body`, and returned by hyper as a "receive stream" (so, for server
    //! requests and client responses).

  • Quality doc comments with clear definitions and informative examples

    enum Kind {
    #[allow(dead_code)]
    Empty,
    Chan {
    content_length: DecodedLength,
    want_tx: watch::Sender,
    data_rx: mpsc::Receiver<Result<Bytes, crate::Error>>,
    trailers_rx: oneshot::Receiver<HeaderMap>,
    },
    #[cfg(all(feature = "http2", any(feature = "client", feature = "server")))]
    H2 {
    content_length: DecodedLength,
    data_done: bool,
    ping: ping::Recorder,
    recv: h2::RecvStream,
    },
    #[cfg(feature = "ffi")]
    Ffi(crate::ffi::UserBody),
    }

  • Get Incoming doc-comment-quality on par with Sender

    /// A stream of `Bytes`, used when receiving bodies from the network.
    #[must_use = "streams do nothing unless polled"]
    pub struct Incoming {
    kind: Kind,
    }

    /// A sender half created through [`Body::channel()`].
    ///
    /// Useful when wanting to stream chunks from another thread.
    ///
    /// ## Body Closing
    ///
    /// Note that the request body will always be closed normally when the sender is dropped (meaning
    /// that the empty terminating chunk will be sent to the remote). If you desire to close the
    /// connection with an incomplete response (e.g. in the case of an error during asynchronous
    /// processing), call the [`Sender::abort()`] method to abort the body in an abnormal fashion.
    ///
    /// [`Body::channel()`]: struct.Body.html#method.channel
    /// [`Sender::abort()`]: struct.Sender.html#method.abort
    #[must_use = "Sender does nothing unless sent on"]
    pub(crate) struct Sender {
    want_rx: watch::Receiver,
    data_tx: BodySender,
    trailers_tx: Option<TrailersSender>,
    }

  • Extend coverage to these Sender pieces

    type BodySender = mpsc::Sender<Result<Bytes, crate::Error>>;
    type TrailersSender = oneshot::Sender<HeaderMap>;


I see that Incoming's body / self implementations are sparse on documentation. Is there interest in spreading coverage there as well?

@seanmonstar
Copy link
Member Author

This looks right to me! Though, the Sender type is now 100% internal, so it's documentation doesn't need to be changed much. I expect some sort of similar channel type will exist in hyper-util, but that's a separate ticket.

Extend module overview with "top-level" perspective of available body types

Yea, I'd probably link to the http-body-util crate as a "read more", and provide a brief overview here about the "kinds" of bodies that could exist (and likely already do in the util crate).

@IsaacCloos
Copy link
Contributor

I'm marinating a draft for this right now, and a few more questions have come to me:

  1. Can the scope of this ticket be updated to include documenting the Body implementing structs in http-body-util? I wish I had really given thought to the full user experience before ascertaining the possibilities of this issue above. Forget all that! I think some real good can come from adding documentation (desc, example, panics, notes) to prefabs like Full, StreamBody, Limited ext.

Yea, I'd probably link to the http-body-util crate as a "read more", and provide a brief overview here about the "kinds" of bodies that could exist (and likely already do in the util crate).

In my honest opinion, sending them over would still leave them wanting more information right now. I'd like to start working in that direction, but want to stay within the parameters of the ticket.

  1. http-body-util is loaded with body "types" that cover a good chunk of usages that the average hyper user would need. I have an instinct to reach into hyper to find these "default profiles" (if you will), but of course they are relegated to a utility crate. For my education, why does hyper not re-export these types if, for example, the server feature is enabled?

aside: bytes and http-body are re-exported tastefully:

hyper/src/body/mod.rs

Lines 17 to 20 in 8552543

pub use bytes::{Buf, Bytes};
pub use http_body::Body;
pub use http_body::Frame;
pub use http_body::SizeHint;

  1. Finally! Are there any specific body types you'd like to see mentioned and/or demonstrated that AREN'T covered in the util? I'm just trying to get all my ducks in a row, and make sure I'm nailing the issue criteria.

Thanks again for your time, and sorry for the question barrage 😅

@seanmonstar
Copy link
Member Author

I have an instinct to reach into hyper to find these "default profiles" (if you will), but of course they are relegated to a utility crate. For my education, why does hyper not re-export these types if, for example, the server feature is enabled?

The primary reason is to disconnect their stability from hyper's stability. For instance, if we wanted to change whether Full had a different default error type, we wouldn't want that to require hyper 2.0.

Are there any specific body types you'd like to see mentioned and/or demonstrated that AREN'T covered in the util?

Probably eventually. For instance, see #2858 of something that would be nice to have, but we aren't blocking 1.0 on having it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-body Area: body streaming. A-docs Area: documentation. E-medium Effort: medium. Some knowledge of how hyper internal works would be useful.
Projects
No open projects
Status: Todo
Development

No branches or pull requests

2 participants