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

update hyper and axum #137

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

update hyper and axum #137

wants to merge 2 commits into from

Conversation

jrobsonchase
Copy link
Contributor

@jrobsonchase jrobsonchase commented Feb 13, 2024

Significant breakage, since hyper 1.0 introduced significant breakage.

Of note:

  • No more Accept trait, and no more hyper-provided server. Examples are all modeled after the axum serve-with-hyper example.
  • Conn now implements the hyper read/write traits, because why not?
  • Our proxy wrapper is ancient and unmaintained, and still uses old hyper 😢

All in all, not super happy about this change. Hyper used to provide a nice pluggable interface where you could bring-your-own listener type, and that's been entirely done away with. Axum didn't fill in the gap very well, and their serve function explicitly takes a TCP listener. Not sure we want to provide yet another accept-serve loop.

Since hyper is 1.0 and stable though, I feel better about providing implementations of the traits that they do offer. Maybe the rest of the ecosystem will catch up and figure out how to not depend on TcpListener directly.

Resolves #126
Resolves #136

Base automatically changed from josh/upgrade-some-deps to main February 13, 2024 16:51
Copy link
Contributor

@bobzilladev bobzilladev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a comment and a nit.

while let Some(conn) = listener.try_next().await? {
let service = service.clone();
let dropref = dropref.clone();
// Spawn a task to handle the connection. That way we can multiple connections
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe "That way we can handle multiple"

let mut make_service = app.into_make_service_with_connect_info::<SocketAddr>();

let server = async move {
while let Some(conn) = listener.try_next().await? {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block shows up a bit, could it be made into a re-usable component for ourselves and users, or does that get too messy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, so this is what I originally tried to do and burned most of monday on.

We could

  • Support hyper's Service trait directly, and expose a generic method that takes one of those. Unfortunately, this means that we can't use axum's Connected trait.
  • Support tower's Service trait. This lets us support axum and its Connected trait better, but ties us to the tower ecosystem. hyper seems like a better bet imo than the higher-level tower APIs, at least for now.

The core issue with hyper's Service is that it expects a Request, which is already interpreted at the protocol level and doesn't include things like the remote addr. Meanwhile, axum's Connected expects that context to be plumbed in through the tower::Service side-channel by seeding it with the original connection stream first before handing the remote-addr-seeded service off to the hyper API.

It's all a mess and I think I'd prefer to support the lowest-common-denominator for now, which seems to be hyper. I'm frustrated that they removed the Accept trait and Server struct and rebased their Service to operate on Requests instead of the connection without providing an alternative. Ideally, axum::serve would've filled that gap, but it's explicitly dependent on TcpListener, so it's a no-go.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eek, makes sense to just be raw hyper and everything else DIY, it's sad they dropped that. I do wonder if these accept loops could be moved to a helper in our sdk so the examples and users would have less to do directly.

@Abdiramen
Copy link

All in all, not super happy about this change. Hyper used to provide a nice pluggable interface where you could bring-your-own listener type, and that's been entirely done away with.

Hopefully, as hyper-utils matures they develop a new pluggable interface.

@zaijie1213
Copy link

When is this PR expected to be integrated?

@3miliano
Copy link

@jrobsonchase @bobzilladev Any chance this will get merge any time soon? I could really use this, since my project is dependent on Hyper 1.0+. Let me know if there is anything I can do to speed this up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update needed due to breaking changes of axum version "0.7.4" release Update to hyper v1
5 participants