Skip to content

Commit b363354

Browse files
novacrazyyanns
authored andcommitted
avoid one state clone
This is an extraction of a part of #2865
1 parent 19b99ea commit b363354

File tree

3 files changed

+21
-18
lines changed

3 files changed

+21
-18
lines changed

axum/src/routing/method_routing.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,27 +1101,24 @@ where
11011101
macro_rules! call {
11021102
(
11031103
$req:expr,
1104-
$method:expr,
11051104
$method_variant:ident,
11061105
$svc:expr
11071106
) => {
1108-
if $method == Method::$method_variant {
1107+
if *req.method() == Method::$method_variant {
11091108
match $svc {
11101109
MethodEndpoint::None => {}
11111110
MethodEndpoint::Route(route) => {
1112-
return route.clone().oneshot_inner($req);
1111+
return route.clone().oneshot_inner_owned($req);
11131112
}
11141113
MethodEndpoint::BoxedHandler(handler) => {
1115-
let mut route = handler.clone().into_route(state);
1116-
return route.oneshot_inner($req);
1114+
let route = handler.clone().into_route(state);
1115+
return route.oneshot_inner_owned($req);
11171116
}
11181117
}
11191118
}
11201119
};
11211120
}
11221121

1123-
let method = req.method().clone();
1124-
11251122
// written with a pattern match like this to ensure we call all routes
11261123
let Self {
11271124
get,
@@ -1137,16 +1134,16 @@ where
11371134
allow_header,
11381135
} = self;
11391136

1140-
call!(req, method, HEAD, head);
1141-
call!(req, method, HEAD, get);
1142-
call!(req, method, GET, get);
1143-
call!(req, method, POST, post);
1144-
call!(req, method, OPTIONS, options);
1145-
call!(req, method, PATCH, patch);
1146-
call!(req, method, PUT, put);
1147-
call!(req, method, DELETE, delete);
1148-
call!(req, method, TRACE, trace);
1149-
call!(req, method, CONNECT, connect);
1137+
call!(req, HEAD, head);
1138+
call!(req, HEAD, get);
1139+
call!(req, GET, get);
1140+
call!(req, POST, post);
1141+
call!(req, OPTIONS, options);
1142+
call!(req, PATCH, patch);
1143+
call!(req, PUT, put);
1144+
call!(req, DELETE, delete);
1145+
call!(req, TRACE, trace);
1146+
call!(req, CONNECT, connect);
11501147

11511148
let future = fallback.clone().call_with_state(req, state);
11521149

axum/src/routing/route.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ impl<E> Route<E> {
4747
RouteFuture::new(method, self.0.clone().oneshot(req))
4848
}
4949

50+
/// Variant of [`Route::oneshot_inner`] that takes ownership of the route to avoid cloning.
51+
pub(crate) fn oneshot_inner_owned(self, req: Request) -> RouteFuture<E> {
52+
let method = req.method().clone();
53+
RouteFuture::new(method, self.0.oneshot(req))
54+
}
55+
5056
pub(crate) fn layer<L, NewError>(self, layer: L) -> Route<NewError>
5157
where
5258
L: Layer<Route<E>> + Clone + Send + 'static,

axum/src/routing/tests/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@ async fn state_isnt_cloned_too_much() {
941941

942942
client.get("/").await;
943943

944-
assert_eq!(COUNT.load(Ordering::SeqCst), 4);
944+
assert_eq!(COUNT.load(Ordering::SeqCst), 3);
945945
}
946946

947947
#[crate::test]

0 commit comments

Comments
 (0)