mirror of
https://github.com/tokio-rs/axum.git
synced 2026-09-06 00:00:17 +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:
@@ -8,7 +8,7 @@ use self::rejection::*;
|
||||
use crate::response::IntoResponse;
|
||||
use async_trait::async_trait;
|
||||
use http::{Extensions, HeaderMap, Method, Request, Uri, Version};
|
||||
use std::convert::Infallible;
|
||||
use std::{convert::Infallible, sync::Arc};
|
||||
|
||||
pub mod rejection;
|
||||
|
||||
@@ -49,7 +49,7 @@ pub use self::from_ref::FromRef;
|
||||
/// where
|
||||
/// // these bounds are required by `async_trait`
|
||||
/// B: Send,
|
||||
/// S: Send,
|
||||
/// S: Send + Sync,
|
||||
/// {
|
||||
/// type Rejection = http::StatusCode;
|
||||
///
|
||||
@@ -79,7 +79,7 @@ pub trait FromRequest<S, B>: Sized {
|
||||
/// Has several convenience methods for getting owned parts of the request.
|
||||
#[derive(Debug)]
|
||||
pub struct RequestParts<S, B> {
|
||||
state: S,
|
||||
pub(crate) state: Arc<S>,
|
||||
method: Method,
|
||||
uri: Uri,
|
||||
version: Version,
|
||||
@@ -110,6 +110,17 @@ impl<S, B> RequestParts<S, B> {
|
||||
///
|
||||
/// [`tower::Service`]: https://docs.rs/tower/lastest/tower/trait.Service.html
|
||||
pub fn with_state(state: S, req: Request<B>) -> Self {
|
||||
Self::with_state_arc(Arc::new(state), req)
|
||||
}
|
||||
|
||||
/// Create a new `RequestParts` with the given [`Arc`]'ed state.
|
||||
///
|
||||
/// You generally shouldn't need to construct this type yourself, unless
|
||||
/// using extractors outside of axum for example to implement a
|
||||
/// [`tower::Service`].
|
||||
///
|
||||
/// [`tower::Service`]: https://docs.rs/tower/lastest/tower/trait.Service.html
|
||||
pub fn with_state_arc(state: Arc<S>, req: Request<B>) -> Self {
|
||||
let (
|
||||
http::request::Parts {
|
||||
method,
|
||||
@@ -153,7 +164,7 @@ impl<S, B> RequestParts<S, B> {
|
||||
/// impl<S, B> FromRequest<S, B> for MyExtractor
|
||||
/// where
|
||||
/// B: Send,
|
||||
/// S: Send,
|
||||
/// S: Send + Sync,
|
||||
/// {
|
||||
/// type Rejection = Infallible;
|
||||
///
|
||||
@@ -285,7 +296,7 @@ impl<S, T, B> FromRequest<S, B> for Option<T>
|
||||
where
|
||||
T: FromRequest<S, B>,
|
||||
B: Send,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
@@ -299,7 +310,7 @@ impl<S, T, B> FromRequest<S, B> for Result<T, T::Rejection>
|
||||
where
|
||||
T: FromRequest<S, B>,
|
||||
B: Send,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ use crate::BoxError;
|
||||
use async_trait::async_trait;
|
||||
use bytes::Bytes;
|
||||
use http::{Extensions, HeaderMap, Method, Request, Uri, Version};
|
||||
use std::convert::Infallible;
|
||||
use std::{convert::Infallible, sync::Arc};
|
||||
|
||||
#[async_trait]
|
||||
impl<S, B> FromRequest<S, B> for Request<B>
|
||||
where
|
||||
B: Send,
|
||||
S: Clone + Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = BodyAlreadyExtracted;
|
||||
|
||||
@@ -17,7 +17,7 @@ where
|
||||
let req = std::mem::replace(
|
||||
req,
|
||||
RequestParts {
|
||||
state: req.state().clone(),
|
||||
state: Arc::clone(&req.state),
|
||||
method: req.method.clone(),
|
||||
version: req.version,
|
||||
uri: req.uri.clone(),
|
||||
@@ -35,7 +35,7 @@ where
|
||||
impl<S, B> FromRequest<S, B> for Method
|
||||
where
|
||||
B: Send,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
@@ -48,7 +48,7 @@ where
|
||||
impl<S, B> FromRequest<S, B> for Uri
|
||||
where
|
||||
B: Send,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
@@ -61,7 +61,7 @@ where
|
||||
impl<S, B> FromRequest<S, B> for Version
|
||||
where
|
||||
B: Send,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
@@ -79,7 +79,7 @@ where
|
||||
impl<S, B> FromRequest<S, B> for HeaderMap
|
||||
where
|
||||
B: Send,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
@@ -94,7 +94,7 @@ where
|
||||
B: http_body::Body + Send,
|
||||
B::Data: Send,
|
||||
B::Error: Into<BoxError>,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = BytesRejection;
|
||||
|
||||
@@ -115,7 +115,7 @@ where
|
||||
B: http_body::Body + Send,
|
||||
B::Data: Send,
|
||||
B::Error: Into<BoxError>,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = StringRejection;
|
||||
|
||||
@@ -137,7 +137,7 @@ where
|
||||
impl<S, B> FromRequest<S, B> for http::request::Parts
|
||||
where
|
||||
B: Send,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::convert::Infallible;
|
||||
impl<S, B> FromRequest<S, B> for ()
|
||||
where
|
||||
B: Send,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Infallible;
|
||||
|
||||
@@ -26,7 +26,7 @@ macro_rules! impl_from_request {
|
||||
where
|
||||
$( $ty: FromRequest<S, B> + Send, )*
|
||||
B: Send,
|
||||
S: Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = Response;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user