-
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
use afit and remove async-trait #2308
Conversation
Are you able to make it actually compile? I'm not totally up to date on the specifics of |
The situation is this: You still can't write a generic function like As such, I think it makes sense to get this in for the next breaking release. It removes a bunch of indirection, and allows auto traits other than |
As for this PR, it introduces a number of trait declarations that don't use |
Thats great news! 🎉 |
It can be compiled on nightly version. rustup default nightly |
Why is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Have now reviewed everything and it looks pretty good, just some minor things could still be improved.
axum-extra/src/either.rs
Outdated
@@ -247,12 +242,12 @@ macro_rules! impl_traits_for_either { | |||
|
|||
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> { | |||
$( | |||
if let Ok(value) = FromRequestParts::from_request_parts(parts, state).await { | |||
if let Ok(value) = $ident::from_request_parts(parts, state).await { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you change this? It means that an inherent from_request_parts
would be called here if it exists in addition to the one from a FromRequestParts
impl, which I don't think is right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because an error occurs if I don't change this.
error[E0282]: type annotations needed
--> axum-extra/src/either.rs:250:17
|
250 | FromRequestParts::from_request_parts(parts, state).await.map(Self::$last)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
...
275 | impl_traits_for_either!(Either8 => [E1, E2, E3, E4, E5, E6, E7], E8);
| -------------------------------------------------------------------- in this macro invocation
|
= note: this error originates in the macro `impl_traits_for_either` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0282`.
error: could not compile `axum-extra` (lib) due to 7 previous errors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed it to this.
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
$(
if let Ok(value) = <$ident as FromRequestParts<S>>::from_request_parts(parts, state).await {
return Ok(Self::$ident(value));
}
)*
<$last as FromRequestParts<S>>::from_request_parts(parts, state).await.map(Self::$last)
}
Because it's impossible for generic functions to declare that they accept any implementer of a given trait where one or all of its async methods return a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I think we can merge this once RPITIT & AFIT hit stable! 🎉
I have rebased it to axum 0.7 |
There are still a lot of macros need to be fixed. ::axum::extract::FromRequest::from_request
should be changed to
<#field_ty as ::axum::extract::FromRequest<#trait_generics, _>>::from_request // the second generic type is private::ViaParts ---- debug_handler::ui stdout ----
thread 'debug_handler::ui' panicked at /Users/lz1998/.cargo/registry/src/rsproxy.cn-8f6827c7555bfaf8/trybuild-1.0.86/src/run.rs:101:13:
6 of 29 tests failed
---- from_request::ui stdout ----
thread 'from_request::ui' panicked at /Users/lz1998/.cargo/registry/src/rsproxy.cn-8f6827c7555bfaf8/trybuild-1.0.86/src/run.rs:101:13:
15 of 58 tests failed
error[E0282]: type annotations needed
--> src/main.rs:22:11
|
22 | host: Result<headers::Host, TypedHeaderRejection>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
@davidpdrsn It's hard to solve the problem of macros because of the second generic type |
Sure I'll try and take a look! |
I have rebased it to the main branch. |
Thanks for all your work on this by the way ❤️ |
Just to add on this, if someone was wondering about the performance implications. (Tested with I am comparing with the following [package]
name = "bench"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
lto = "thin"
codegen-units = 1
[dependencies]
tokio = { version = "1", features = [ "full" ] }
# This PR
axum = { git = "https://github.com/lz1998/axum.git", branch = "main" }
# Upstream
#axum = { git = "https://github.com/tokio-rs/axum.git", rev = "c1c917092daeb91456b41510b629c4ba9763b2b6" } and this use axum::{
routing::get,
Router,
};
#[tokio::main]
async fn main() {
// build our application with a single route
let app = Router::new()
.route("/", get(|| async { "Hello, World!" }));
// run our app with hyper, listening globally on port 3000
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
} Baseline results
PR results
As you can see, latency and throughput improves with almost no difference in binary size Also interesting that the P99 latency for -c1 is halved |
There is a chance, though getting a release out is a lot more involved (due to the matchit upgrade, but also a few other planned changes). Anyways.. @lz1998 I just fixed merge conflicts for you, would you mind taking another look at the current CI failures? |
The commented line will cause an error, because the second generic type use axum::extract::{FromRequest, Request};
use axum_extra::{
TypedHeader,
headers::{UserAgent},
};
struct MyExtractor {}
impl<S: Send + Sync> FromRequest<S> for MyExtractor {
type Rejection = ();
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
// let _ = <TypedHeader::<UserAgent> as FromRequest<S>>::from_request(req, state).await;
let _ = TypedHeader::<UserAgent>::from_request(req, state).await;
Ok(MyExtractor {})
}
}
#[tokio::main]
async fn main() {} error[E0277]: the trait bound `TypedHeader<UserAgent>: FromRequest<S>` is not satisfied
--> src/main.rs:18:18
|
18 | let _ = <TypedHeader::<UserAgent> as FromRequest<S>>::from_request(req, state).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromRequest<S>` is not implemented for `TypedHeader<UserAgent>`
|
= note: Function argument is not a valid axum extractor.
See `https://docs.rs/axum/0.7/axum/extract/index.html` for details
= help: the following other types implement trait `FromRequest<S, M>`:
(T1, T2)
(T1, T2, T3)
(T1, T2, T3, T4)
(T1, T2, T3, T4, T5)
(T1, T2, T3, T4, T5, T6)
(T1, T2, T3, T4, T5, T6, T7)
(T1, T2, T3, T4, T5, T6, T7, T8)
(T1, T2, T3, T4, T5, T6, T7, T8, T9)
and 20 others |
Yeah, in that case you wouldn't use |
Oh, that code isn't what we actually have as an example whatever, it's macro-generated? I don't see how this would be a new problem though.. Will look at what changed in the macro code. |
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
Small tip, instead of accepting every suggestion individually, you can go to the files tab of the PR and batch them up into a single commit 😉 Also, I opened #2943 for the MSRV bump that's needed for this. |
Is it possible to get a beta release with this patch included? |
I was planning to do a pre-release soon, yes. I'll probably wait until we have merged the matchit upgrade though. |
This is out as part of the latest set of alpha releases :) |
Motivation
rust-lang/rust#115822
1.75.0 will be stable on: 28 December, 2023.
Remove
async-trait
and use AFIT(Async Fn In Trait) and RPITIT(Return Position Impl Trait In Traits).Solution