Replace custom BoxCloneService struct with tower::util::BoxCloneSyncService (#3109)

This commit is contained in:
Tobias Bieniek 2024-12-27 08:57:52 +01:00 committed by GitHub
parent a5de589274
commit 8def6782fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 35 additions and 239 deletions

View file

@ -1,4 +1,4 @@
allow-mixed-uninlined-format-args = false
disallowed-types = [
{ path = "tower::util::BoxCloneService", reason = "Use our internal BoxCloneService which is Sync" },
{ path = "tower::util::BoxCloneService", reason = "Use tower::util::BoxCloneSyncService instead" },
]

137
Cargo.lock generated
View file

@ -415,7 +415,7 @@ dependencies = [
"multer",
"percent-encoding",
"pin-project-lite",
"prost 0.13.4",
"prost",
"reqwest 0.12.9",
"serde",
"serde_html_form",
@ -610,7 +610,7 @@ dependencies = [
"lazy_static",
"lazycell",
"log",
"prettyplease 0.2.25",
"prettyplease",
"proc-macro2",
"quote",
"regex",
@ -1239,7 +1239,7 @@ checksum = "c5d9abe6314103864cc2d8901b7ae224e0ab1a103a0a416661b4097b0779b607"
dependencies = [
"darling",
"either",
"heck 0.5.0",
"heck",
"proc-macro2",
"quote",
"syn 2.0.91",
@ -1275,7 +1275,7 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
dependencies = [
"heck 0.5.0",
"heck",
"proc-macro2",
"quote",
"syn 2.0.91",
@ -1739,17 +1739,6 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "example-rest-grpc-multiplex"
version = "0.1.0"
dependencies = [
"axum",
"futures",
"hyper 1.5.2",
"tonic-build",
"tower 0.5.2",
]
[[package]]
name = "example-reverse-proxy"
version = "0.1.0"
@ -2040,12 +2029,6 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fixedbitset"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flate2"
version = "1.0.35"
@ -2363,12 +2346,6 @@ dependencies = [
"http 1.2.0",
]
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "heck"
version = "0.5.0"
@ -2912,15 +2889,6 @@ dependencies = [
"serde",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.12.1"
@ -3305,12 +3273,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "multimap"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
[[package]]
name = "native-tls"
version = "0.2.12"
@ -3581,16 +3543,6 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "petgraph"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
dependencies = [
"fixedbitset",
"indexmap 2.7.0",
]
[[package]]
name = "phf"
version = "0.11.2"
@ -3739,16 +3691,6 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "prettyplease"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86"
dependencies = [
"proc-macro2",
"syn 1.0.109",
]
[[package]]
name = "prettyplease"
version = "0.2.25"
@ -3792,16 +3734,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "prost"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
dependencies = [
"bytes",
"prost-derive 0.11.9",
]
[[package]]
name = "prost"
version = "0.13.4"
@ -3809,42 +3741,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec"
dependencies = [
"bytes",
"prost-derive 0.13.4",
]
[[package]]
name = "prost-build"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270"
dependencies = [
"bytes",
"heck 0.4.1",
"itertools 0.10.5",
"lazy_static",
"log",
"multimap",
"petgraph",
"prettyplease 0.1.25",
"prost 0.11.9",
"prost-types",
"regex",
"syn 1.0.109",
"tempfile",
"which",
]
[[package]]
name = "prost-derive"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
dependencies = [
"anyhow",
"itertools 0.10.5",
"proc-macro2",
"quote",
"syn 1.0.109",
"prost-derive",
]
[[package]]
@ -3860,15 +3757,6 @@ dependencies = [
"syn 2.0.91",
]
[[package]]
name = "prost-types"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13"
dependencies = [
"prost 0.11.9",
]
[[package]]
name = "quanta"
version = "0.12.4"
@ -4809,7 +4697,7 @@ checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5"
dependencies = [
"dotenvy",
"either",
"heck 0.5.0",
"heck",
"hex",
"once_cell",
"proc-macro2",
@ -5362,19 +5250,6 @@ dependencies = [
"winnow",
]
[[package]]
name = "tonic-build"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07"
dependencies = [
"prettyplease 0.1.25",
"proc-macro2",
"prost-build",
"quote",
"syn 1.0.109",
]
[[package]]
name = "tower"
version = "0.4.13"

View file

@ -52,7 +52,7 @@ http-body-util = "0.1.0"
mime = "0.3"
pin-project-lite = "0.2"
serde = "1.0"
tower = { version = "0.5.1", default-features = false, features = ["util"] }
tower = { version = "0.5.2", default-features = false, features = ["util"] }
tower-layer = "0.3"
tower-service = "0.3"
@ -83,7 +83,7 @@ reqwest = { version = "0.12", default-features = false, features = ["json", "str
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.71"
tokio = { version = "1.14", features = ["full"] }
tower = { version = "0.5.1", features = ["util"] }
tower = { version = "0.5.2", features = ["util"] }
tower-http = { version = "0.6.0", features = ["map-response-body", "timeout"] }
[lints]

View file

@ -61,7 +61,7 @@ pin-project-lite = "0.2.7"
rustversion = "1.0.9"
serde = "1.0"
sync_wrapper = "1.0.0"
tower = { version = "0.5.1", default-features = false, features = ["util"] }
tower = { version = "0.5.2", default-features = false, features = ["util"] }
tower-layer = "0.3.2"
tower-service = "0.3"
@ -135,7 +135,7 @@ uuid = { version = "1.0", features = ["serde", "v4"] }
[dev-dependencies.tower]
package = "tower"
version = "0.5.1"
version = "0.5.2"
features = [
"util",
"timeout",

View file

@ -1,80 +0,0 @@
use futures_util::future::BoxFuture;
use std::{
fmt,
task::{Context, Poll},
};
use tower::ServiceExt;
use tower_service::Service;
/// Like `tower::BoxCloneService` but `Sync`
pub(crate) struct BoxCloneService<T, U, E>(
Box<
dyn CloneService<T, Response = U, Error = E, Future = BoxFuture<'static, Result<U, E>>>
+ Send
+ Sync,
>,
);
impl<T, U, E> BoxCloneService<T, U, E> {
pub(crate) fn new<S>(inner: S) -> Self
where
S: Service<T, Response = U, Error = E> + Clone + Send + Sync + 'static,
S::Future: Send + 'static,
{
let inner = inner.map_future(|f| Box::pin(f) as _);
BoxCloneService(Box::new(inner))
}
}
impl<T, U, E> Service<T> for BoxCloneService<T, U, E> {
type Response = U;
type Error = E;
type Future = BoxFuture<'static, Result<U, E>>;
#[inline]
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
self.0.poll_ready(cx)
}
#[inline]
fn call(&mut self, request: T) -> Self::Future {
self.0.call(request)
}
}
impl<T, U, E> Clone for BoxCloneService<T, U, E> {
fn clone(&self) -> Self {
Self(self.0.clone_box())
}
}
trait CloneService<R>: Service<R> {
fn clone_box(
&self,
) -> Box<
dyn CloneService<R, Response = Self::Response, Error = Self::Error, Future = Self::Future>
+ Send
+ Sync,
>;
}
impl<R, T> CloneService<R> for T
where
T: Service<R> + Send + Sync + Clone + 'static,
{
fn clone_box(
&self,
) -> Box<
dyn CloneService<R, Response = T::Response, Error = T::Error, Future = T::Future>
+ Send
+ Sync,
> {
Box::new(self.clone())
}
}
impl<T, U, E> fmt::Debug for BoxCloneService<T, U, E> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("BoxCloneService").finish()
}
}

View file

@ -427,7 +427,6 @@
#[macro_use]
pub(crate) mod macros;
mod box_clone_service;
mod boxed;
mod extension;
#[cfg(feature = "form")]

View file

@ -1,4 +1,3 @@
use crate::box_clone_service::BoxCloneService;
use crate::response::{IntoResponse, Response};
use axum_core::extract::{FromRequest, FromRequestParts, Request};
use futures_util::future::BoxFuture;
@ -11,6 +10,7 @@ use std::{
pin::Pin,
task::{Context, Poll},
};
use tower::util::BoxCloneSyncService;
use tower::ServiceBuilder;
use tower_layer::Layer;
use tower_service::Service;
@ -302,7 +302,7 @@ macro_rules! impl_service {
};
let inner = ServiceBuilder::new()
.layer_fn(BoxCloneService::new)
.layer_fn(BoxCloneSyncService::new)
.map_response(IntoResponse::into_response)
.service(ready_inner);
let next = Next { inner };
@ -337,7 +337,7 @@ where
/// The remainder of a middleware stack, including the handler.
#[derive(Debug, Clone)]
pub struct Next {
inner: BoxCloneService<Request, Response, Infallible>,
inner: BoxCloneSyncService<Request, Response, Infallible>,
}
impl Next {

View file

@ -1,6 +1,5 @@
use crate::{
body::{Body, HttpBody},
box_clone_service::BoxCloneService,
response::Response,
};
use axum_core::{extract::Request, response::IntoResponse};
@ -18,7 +17,7 @@ use std::{
task::{ready, Context, Poll},
};
use tower::{
util::{MapErrLayer, MapResponseLayer, Oneshot},
util::{BoxCloneSyncService, MapErrLayer, MapResponseLayer, Oneshot},
ServiceExt,
};
use tower_layer::Layer;
@ -28,7 +27,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>(BoxCloneSyncService<Request, Response, E>);
impl<E> Route<E> {
pub(crate) fn new<T>(svc: T) -> Self
@ -37,7 +36,7 @@ impl<E> Route<E> {
T::Response: IntoResponse + 'static,
T::Future: Send + 'static,
{
Self(BoxCloneService::new(
Self(BoxCloneSyncService::new(
svc.map_response(IntoResponse::into_response),
))
}
@ -115,7 +114,7 @@ pin_project! {
/// Response future for [`Route`].
pub struct RouteFuture<E> {
#[pin]
inner: Oneshot<BoxCloneService<Request, Response, E>, Request>,
inner: Oneshot<BoxCloneSyncService<Request, Response, E>, Request>,
method: Method,
allow_header: Option<Bytes>,
top_level: bool,
@ -123,7 +122,10 @@ pin_project! {
}
impl<E> RouteFuture<E> {
fn new(method: Method, inner: Oneshot<BoxCloneService<Request, Response, E>, Request>) -> Self {
fn new(
method: Method,
inner: Oneshot<BoxCloneSyncService<Request, Response, E>, Request>,
) -> Self {
Self {
inner,
method,

View file

@ -8,7 +8,7 @@ publish = false
axum = { path = "../../axum" }
serde_json = "1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
tower = "0.5.1"
tower = "0.5.2"
tower-http = { version = "0.6.1", features = ["compression-full", "decompression-full"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

View file

@ -11,4 +11,4 @@ tokio = { version = "1.0", features = ["full"] }
[dev-dependencies]
http-body-util = "0.1.0"
hyper = { version = "1.0.0", features = ["full"] }
tower = { version = "0.5.1", features = ["util"] }
tower = { version = "0.5.2", features = ["util"] }

View file

@ -9,6 +9,6 @@ axum = { path = "../../axum" }
hyper = { version = "1", features = ["full"] }
hyper-util = "0.1.1"
tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.5.1", features = ["make", "util"] }
tower = { version = "0.5.2", features = ["make", "util"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

View file

@ -7,7 +7,7 @@ publish = false
[dependencies]
axum = { path = "../../axum" }
tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.5.1", features = ["util", "timeout", "load-shed", "limit"] }
tower = { version = "0.5.2", features = ["util", "timeout", "load-shed", "limit"] }
tower-http = { version = "0.6.1", features = [
"add-extension",
"auth",

View file

@ -11,7 +11,7 @@ hyper = { version = "1.0.0", features = ["full"] }
hyper-util = { version = "0.1" }
tokio = { version = "1", features = ["full"] }
tokio-native-tls = "0.3.1"
tower = { version = "0.5.1", features = ["make"] }
tower = { version = "0.5.2", features = ["make"] }
tower-service = "0.3.2"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

View file

@ -12,6 +12,6 @@ hyper-util = { version = "0.1" }
openssl = "0.10"
tokio = { version = "1", features = ["full"] }
tokio-openssl = "0.6"
tower = { version = "0.5.1", features = ["make"] }
tower = { version = "0.5.2", features = ["make"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

View file

@ -9,4 +9,4 @@ axum = { path = "../../axum" }
http-body-util = "0.1.0"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.5.1", features = ["util"] }
tower = { version = "0.5.2", features = ["util"] }

View file

@ -7,7 +7,7 @@ publish = false
[dependencies]
axum = { path = "../../axum" }
tokio = { version = "1.0", features = ["full"] }
tower = "0.5"
tower = "0.5.2"
tower-http = { version = "0.5", features = ["request-id", "trace"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

View file

@ -9,4 +9,4 @@ axum = { path = "../../axum" }
hyper = { version = "1.0", features = [] }
hyper-util = { version = "0.1", features = ["tokio", "server-auto", "http1"] }
tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.5.1", features = ["util"] }
tower = { version = "0.5.2", features = ["util"] }

View file

@ -7,7 +7,7 @@ publish = false
[dependencies]
axum = { path = "../../axum" }
tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.5.1", features = ["util"] }
tower = { version = "0.5.2", features = ["util"] }
tower-http = { version = "0.6.1", features = ["fs", "trace"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

View file

@ -16,4 +16,4 @@ tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
[dev-dependencies]
tower = { version = "0.5.1", features = ["util"] }
tower = { version = "0.5.2", features = ["util"] }

View file

@ -8,7 +8,7 @@ publish = false
axum = { path = "../../axum" }
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.5.1", features = ["util", "timeout"] }
tower = { version = "0.5.2", features = ["util", "timeout"] }
tower-http = { version = "0.6.1", features = ["add-extension", "trace"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

View file

@ -10,5 +10,5 @@ http-body-util = "0.1"
hyper = { version = "1.0.0", features = ["full"] }
hyper-util = { version = "0.1", features = ["tokio", "server-auto", "http1"] }
tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.5.1", features = ["util"] }
tower = { version = "0.5.2", features = ["util"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }