From af13c539386463b04b82f58155ee04702527212b Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Tue, 2 Jan 2024 20:18:07 +0100 Subject: [PATCH] Make Router Sync without breaking the API (#2481) --- axum/src/boxed.rs | 18 +++++++++--------- axum/src/routing/mod.rs | 1 + axum/src/routing/route.rs | 11 ++++++----- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/axum/src/boxed.rs b/axum/src/boxed.rs index 5473b2491b..69fda3fd98 100644 --- a/axum/src/boxed.rs +++ b/axum/src/boxed.rs @@ -1,4 +1,4 @@ -use std::{convert::Infallible, fmt}; +use std::{convert::Infallible, fmt, sync::Mutex}; use crate::extract::Request; use tower::Service; @@ -9,7 +9,7 @@ use crate::{ Router, }; -pub(crate) struct BoxedIntoRoute(Box>); +pub(crate) struct BoxedIntoRoute(Mutex>>); impl BoxedIntoRoute where @@ -20,10 +20,10 @@ where H: Handler, T: 'static, { - Self(Box::new(MakeErasedHandler { + Self(Mutex::new(Box::new(MakeErasedHandler { handler, into_route: |handler, state| Route::new(Handler::with_state(handler, state)), - })) + }))) } } @@ -35,20 +35,20 @@ impl BoxedIntoRoute { F: FnOnce(Route) -> Route + Clone + Send + 'static, E2: 'static, { - BoxedIntoRoute(Box::new(Map { - inner: self.0, + BoxedIntoRoute(Mutex::new(Box::new(Map { + inner: self.0.into_inner().unwrap(), layer: Box::new(f), - })) + }))) } pub(crate) fn into_route(self, state: S) -> Route { - self.0.into_route(state) + self.0.into_inner().unwrap().into_route(state) } } impl Clone for BoxedIntoRoute { fn clone(&self) -> Self { - Self(self.0.clone_box()) + Self(Mutex::new(self.0.lock().unwrap().clone_box())) } } diff --git a/axum/src/routing/mod.rs b/axum/src/routing/mod.rs index 13b5725549..49237e4eb8 100644 --- a/axum/src/routing/mod.rs +++ b/axum/src/routing/mod.rs @@ -682,4 +682,5 @@ impl fmt::Debug for Endpoint { fn traits() { use crate::test_helpers::*; assert_send::>(); + assert_sync::>(); } diff --git a/axum/src/routing/route.rs b/axum/src/routing/route.rs index fd63d0e8d0..4f3cffd747 100644 --- a/axum/src/routing/route.rs +++ b/axum/src/routing/route.rs @@ -14,6 +14,7 @@ use std::{ fmt, future::Future, pin::Pin, + sync::Mutex, task::{Context, Poll}, }; use tower::{ @@ -27,7 +28,7 @@ use tower_service::Service; /// /// You normally shouldn't need to care about this type. It's used in /// [`Router::layer`](super::Router::layer). -pub struct Route(BoxCloneService); +pub struct Route(Mutex>); impl Route { pub(crate) fn new(svc: T) -> Self @@ -36,16 +37,16 @@ impl Route { T::Response: IntoResponse + 'static, T::Future: Send + 'static, { - Self(BoxCloneService::new( + Self(Mutex::new(BoxCloneService::new( svc.map_response(IntoResponse::into_response), - )) + ))) } pub(crate) fn oneshot_inner( &mut self, req: Request, ) -> Oneshot, Request> { - self.0.clone().oneshot(req) + self.0.get_mut().unwrap().clone().oneshot(req) } pub(crate) fn layer(self, layer: L) -> Route @@ -70,7 +71,7 @@ impl Route { impl Clone for Route { fn clone(&self) -> Self { - Self(self.0.clone()) + Self(Mutex::new(self.0.lock().unwrap().clone())) } }