mirror of
https://github.com/tokio-rs/axum.git
synced 2024-11-21 22:56:46 +01:00
Avoid one state clone
This is an extraction of a part of https://github.com/tokio-rs/axum/pull/2865
This commit is contained in:
parent
c2e7fc0b3d
commit
0d4e224cae
3 changed files with 31 additions and 20 deletions
|
@ -1097,32 +1097,35 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn call_with_state(&self, req: Request, state: S) -> RouteFuture<E> {
|
pub(crate) fn call_with_state(&self, req: Request, state: S) -> RouteFuture<E> {
|
||||||
|
let method = req.method();
|
||||||
|
let is_head = *method == Method::HEAD;
|
||||||
|
|
||||||
macro_rules! call {
|
macro_rules! call {
|
||||||
(
|
(
|
||||||
$req:expr,
|
|
||||||
$method:expr,
|
|
||||||
$method_variant:ident,
|
$method_variant:ident,
|
||||||
$svc:expr
|
$svc:expr
|
||||||
) => {
|
) => {
|
||||||
if $method == Method::$method_variant {
|
if *method == Method::$method_variant {
|
||||||
match $svc {
|
match $svc {
|
||||||
MethodEndpoint::None => {}
|
MethodEndpoint::None => {}
|
||||||
MethodEndpoint::Route(route) => {
|
MethodEndpoint::Route(route) => {
|
||||||
return RouteFuture::from_future(route.clone().oneshot_inner($req))
|
return RouteFuture::from_future(
|
||||||
.strip_body($method == Method::HEAD);
|
route.clone().oneshot_inner_owned(req),
|
||||||
|
)
|
||||||
|
.strip_body(is_head);
|
||||||
}
|
}
|
||||||
MethodEndpoint::BoxedHandler(handler) => {
|
MethodEndpoint::BoxedHandler(handler) => {
|
||||||
let route = handler.clone().into_route(state);
|
let route = handler.clone().into_route(state);
|
||||||
return RouteFuture::from_future(route.clone().oneshot_inner($req))
|
return RouteFuture::from_future(
|
||||||
.strip_body($method == Method::HEAD);
|
route.clone().oneshot_inner_owned(req),
|
||||||
|
)
|
||||||
|
.strip_body(is_head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let method = req.method().clone();
|
|
||||||
|
|
||||||
// written with a pattern match like this to ensure we call all routes
|
// written with a pattern match like this to ensure we call all routes
|
||||||
let Self {
|
let Self {
|
||||||
get,
|
get,
|
||||||
|
@ -1138,16 +1141,16 @@ where
|
||||||
allow_header,
|
allow_header,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
call!(req, method, HEAD, head);
|
call!(HEAD, head);
|
||||||
call!(req, method, HEAD, get);
|
call!(HEAD, get);
|
||||||
call!(req, method, GET, get);
|
call!(GET, get);
|
||||||
call!(req, method, POST, post);
|
call!(POST, post);
|
||||||
call!(req, method, OPTIONS, options);
|
call!(OPTIONS, options);
|
||||||
call!(req, method, PATCH, patch);
|
call!(PATCH, patch);
|
||||||
call!(req, method, PUT, put);
|
call!(PUT, put);
|
||||||
call!(req, method, DELETE, delete);
|
call!(DELETE, delete);
|
||||||
call!(req, method, TRACE, trace);
|
call!(TRACE, trace);
|
||||||
call!(req, method, CONNECT, connect);
|
call!(CONNECT, connect);
|
||||||
|
|
||||||
let future = fallback.clone().call_with_state(req, state);
|
let future = fallback.clone().call_with_state(req, state);
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,14 @@ impl<E> Route<E> {
|
||||||
self.0.get_mut().unwrap().clone().oneshot(req)
|
self.0.get_mut().unwrap().clone().oneshot(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Variant of [`Route::oneshot_inner`] that takes ownership of the route to avoid cloning.
|
||||||
|
pub(crate) fn oneshot_inner_owned(
|
||||||
|
self,
|
||||||
|
req: Request,
|
||||||
|
) -> Oneshot<BoxCloneService<Request, Response, E>, Request> {
|
||||||
|
self.0.into_inner().unwrap().oneshot(req)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn layer<L, NewError>(self, layer: L) -> Route<NewError>
|
pub(crate) fn layer<L, NewError>(self, layer: L) -> Route<NewError>
|
||||||
where
|
where
|
||||||
L: Layer<Route<E>> + Clone + Send + 'static,
|
L: Layer<Route<E>> + Clone + Send + 'static,
|
||||||
|
|
|
@ -952,7 +952,7 @@ async fn state_isnt_cloned_too_much() {
|
||||||
|
|
||||||
client.get("/").await;
|
client.get("/").await;
|
||||||
|
|
||||||
assert_eq!(COUNT.load(Ordering::SeqCst), 4);
|
assert_eq!(COUNT.load(Ordering::SeqCst), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::test]
|
#[crate::test]
|
||||||
|
|
Loading…
Reference in a new issue