mirror of
https://github.com/tokio-rs/axum.git
synced 2025-01-11 12:31:25 +01:00
Make Router Sync without breaking the API (#2481)
This commit is contained in:
parent
ae244b1eb1
commit
af13c53938
3 changed files with 16 additions and 14 deletions
|
@ -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<S, E>(Box<dyn ErasedIntoRoute<S, E>>);
|
||||
pub(crate) struct BoxedIntoRoute<S, E>(Mutex<Box<dyn ErasedIntoRoute<S, E>>>);
|
||||
|
||||
impl<S> BoxedIntoRoute<S, Infallible>
|
||||
where
|
||||
|
@ -20,10 +20,10 @@ where
|
|||
H: Handler<T, S>,
|
||||
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<S, E> BoxedIntoRoute<S, E> {
|
|||
F: FnOnce(Route<E>) -> Route<E2> + 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<E> {
|
||||
self.0.into_route(state)
|
||||
self.0.into_inner().unwrap().into_route(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, E> Clone for BoxedIntoRoute<S, E> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone_box())
|
||||
Self(Mutex::new(self.0.lock().unwrap().clone_box()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -682,4 +682,5 @@ impl<S> fmt::Debug for Endpoint<S> {
|
|||
fn traits() {
|
||||
use crate::test_helpers::*;
|
||||
assert_send::<Router<()>>();
|
||||
assert_sync::<Router<()>>();
|
||||
}
|
||||
|
|
|
@ -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<E = Infallible>(BoxCloneService<Request, Response, E>);
|
||||
pub struct Route<E = Infallible>(Mutex<BoxCloneService<Request, Response, E>>);
|
||||
|
||||
impl<E> Route<E> {
|
||||
pub(crate) fn new<T>(svc: T) -> Self
|
||||
|
@ -36,16 +37,16 @@ impl<E> Route<E> {
|
|||
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<BoxCloneService<Request, Response, E>, Request> {
|
||||
self.0.clone().oneshot(req)
|
||||
self.0.get_mut().unwrap().clone().oneshot(req)
|
||||
}
|
||||
|
||||
pub(crate) fn layer<L, NewError>(self, layer: L) -> Route<NewError>
|
||||
|
@ -70,7 +71,7 @@ impl<E> Route<E> {
|
|||
|
||||
impl<E> Clone for Route<E> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone())
|
||||
Self(Mutex::new(self.0.lock().unwrap().clone()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue