mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-27 00:00:24 +02:00
Always store state in an Arc (#1270)
* Add extension and state benchmarks * wip * Arc the state everywhere * don't require `S: Clone` * fix example
This commit is contained in:
@@ -6,7 +6,7 @@ use axum::{
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use futures_util::future::{BoxFuture, FutureExt, Map};
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
use std::{future::Future, marker::PhantomData, sync::Arc};
|
||||
|
||||
mod or;
|
||||
|
||||
@@ -24,7 +24,11 @@ pub trait HandlerCallWithExtractors<T, S, B>: Sized {
|
||||
type Future: Future<Output = Response> + Send + 'static;
|
||||
|
||||
/// Call the handler with the extracted inputs.
|
||||
fn call(self, state: S, extractors: T) -> <Self as HandlerCallWithExtractors<T, S, B>>::Future;
|
||||
fn call(
|
||||
self,
|
||||
state: Arc<S>,
|
||||
extractors: T,
|
||||
) -> <Self as HandlerCallWithExtractors<T, S, B>>::Future;
|
||||
|
||||
/// Conver this `HandlerCallWithExtractors` into [`Handler`].
|
||||
fn into_handler(self) -> IntoHandler<Self, T, S, B> {
|
||||
@@ -70,7 +74,7 @@ pub trait HandlerCallWithExtractors<T, S, B>: Sized {
|
||||
/// impl<S, B> FromRequest<S, B> for AdminPermissions
|
||||
/// where
|
||||
/// B: Send,
|
||||
/// S: Send,
|
||||
/// S: Send + Sync,
|
||||
/// {
|
||||
/// // check for admin permissions...
|
||||
/// # type Rejection = ();
|
||||
@@ -85,7 +89,7 @@ pub trait HandlerCallWithExtractors<T, S, B>: Sized {
|
||||
/// impl<S, B> FromRequest<S, B> for User
|
||||
/// where
|
||||
/// B: Send,
|
||||
/// S: Send,
|
||||
/// S: Send + Sync,
|
||||
/// {
|
||||
/// // check for a logged in user...
|
||||
/// # type Rejection = ();
|
||||
@@ -130,7 +134,7 @@ macro_rules! impl_handler_call_with {
|
||||
|
||||
fn call(
|
||||
self,
|
||||
_state: S,
|
||||
_state: Arc<S>,
|
||||
($($ty,)*): ($($ty,)*),
|
||||
) -> <Self as HandlerCallWithExtractors<($($ty,)*), S, B>>::Future {
|
||||
self($($ty,)*).map(IntoResponse::into_response)
|
||||
@@ -172,13 +176,13 @@ where
|
||||
T: FromRequest<S, B> + Send + 'static,
|
||||
T::Rejection: Send,
|
||||
B: Send + 'static,
|
||||
S: Clone + Send + 'static,
|
||||
S: Send + Sync + 'static,
|
||||
{
|
||||
type Future = BoxFuture<'static, Response>;
|
||||
|
||||
fn call(self, state: S, req: http::Request<B>) -> Self::Future {
|
||||
fn call(self, state: Arc<S>, req: http::Request<B>) -> Self::Future {
|
||||
Box::pin(async move {
|
||||
let mut req = RequestParts::with_state(state.clone(), req);
|
||||
let mut req = RequestParts::with_state_arc(Arc::clone(&state), req);
|
||||
match req.extract::<T>().await {
|
||||
Ok(t) => self.handler.call(state, t).await,
|
||||
Err(rejection) => rejection.into_response(),
|
||||
|
||||
@@ -8,7 +8,7 @@ use axum::{
|
||||
};
|
||||
use futures_util::future::{BoxFuture, Either as EitherFuture, FutureExt, Map};
|
||||
use http::StatusCode;
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
use std::{future::Future, marker::PhantomData, sync::Arc};
|
||||
|
||||
/// [`Handler`] that runs one [`Handler`] and if that rejects it'll fallback to another
|
||||
/// [`Handler`].
|
||||
@@ -37,7 +37,7 @@ where
|
||||
|
||||
fn call(
|
||||
self,
|
||||
state: S,
|
||||
state: Arc<S>,
|
||||
extractors: Either<Lt, Rt>,
|
||||
) -> <Self as HandlerCallWithExtractors<Either<Lt, Rt>, S, B>>::Future {
|
||||
match extractors {
|
||||
@@ -64,14 +64,14 @@ where
|
||||
Lt::Rejection: Send,
|
||||
Rt::Rejection: Send,
|
||||
B: Send + 'static,
|
||||
S: Clone + Send + 'static,
|
||||
S: Send + Sync + 'static,
|
||||
{
|
||||
// this puts `futures_util` in our public API but thats fine in axum-extra
|
||||
type Future = BoxFuture<'static, Response>;
|
||||
|
||||
fn call(self, state: S, req: Request<B>) -> Self::Future {
|
||||
fn call(self, state: Arc<S>, req: Request<B>) -> Self::Future {
|
||||
Box::pin(async move {
|
||||
let mut req = RequestParts::with_state(state.clone(), req);
|
||||
let mut req = RequestParts::with_state_arc(Arc::clone(&state), req);
|
||||
|
||||
if let Ok(lt) = req.extract::<Lt>().await {
|
||||
return self.lhs.call(state, lt).await;
|
||||
|
||||
Reference in New Issue
Block a user