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:
David Pedersen
2022-08-17 20:08:24 +00:00
committed by GitHub
parent 423308de3c
commit e7f1c88cd4
56 changed files with 199 additions and 141 deletions
+17 -6
View File
@@ -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;
+10 -10
View File
@@ -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;
+2 -2
View File
@@ -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;