From b113389e23c3343bc932b4c27ec618d153f6e4a3 Mon Sep 17 00:00:00 2001 From: jlizen Date: Fri, 20 Dec 2024 23:12:34 +0000 Subject: [PATCH] add ServiceBuilder::boxed_clone_sync helper --- tower/src/builder/mod.rs | 62 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tower/src/builder/mod.rs b/tower/src/builder/mod.rs index 8f081d234..6c749c346 100644 --- a/tower/src/builder/mod.rs +++ b/tower/src/builder/mod.rs @@ -789,6 +789,68 @@ impl ServiceBuilder { { self.layer(crate::util::BoxCloneService::layer()) } + + /// This wraps the inner service with the [`Layer`] returned by [`BoxCloneSyncServiceLayer`]. + /// + /// This is similar to the [`boxed_clone`] method, but it requires that `Self` implement + /// [`Sync`], and the returned boxed service implements [`Sync`]. + /// + /// See [`BoxCloneSyncService`] for more details. + /// + /// # Example + /// + /// ``` + /// use tower::{Service, ServiceBuilder, BoxError, util::BoxCloneSyncService}; + /// use std::time::Duration; + /// # + /// # struct Request; + /// # struct Response; + /// # impl Response { + /// # fn new() -> Self { Self } + /// # } + /// + /// let service: BoxCloneSyncService = ServiceBuilder::new() + /// .load_shed() + /// .concurrency_limit(64) + /// .timeout(Duration::from_secs(10)) + /// .boxed_clone_sync() + /// .service_fn(|req: Request| async { + /// Ok::<_, BoxError>(Response::new()) + /// }); + /// # let service = assert_service(service); + /// + /// // The boxed service can still be cloned. + /// service.clone(); + /// # fn assert_service(svc: S) -> S + /// # where S: Service { svc } + /// ``` + /// + /// [`BoxCloneSyncServiceLayer`]: crate::util::BoxCloneSyncServiceLayer + /// [`BoxCloneSyncService`]: crate::util::BoxCloneSyncService + /// [`boxed_clone`]: Self::boxed_clone + #[cfg(feature = "util")] + pub fn boxed_clone_sync( + self, + ) -> ServiceBuilder< + Stack< + crate::util::BoxCloneSyncServiceLayer< + S, + R, + >::Response, + >::Error, + >, + Identity, + >, + > + where + L: Layer + Send + Sync + 'static, + L::Service: Service + Clone + Send + Sync + 'static, + >::Future: Send + Sync + 'static, + { + let layer = self.into_inner(); + + ServiceBuilder::new().layer(crate::util::BoxCloneSyncServiceLayer::new(layer)) + } } impl fmt::Debug for ServiceBuilder {