Skip to content

Commit

Permalink
refactor(service): change Service::call to take &self
Browse files Browse the repository at this point in the history
change Service::call to take &self instead of &mut self.
Because of this change, the trait bound in the service::util::service_fn and
the trait bound in the impl for the ServiceFn struct were changed from FnMut to Fn.
This change was decided on for the following reasons:
- It prepares the way for async fn,
  since then the future only borrows &self, and thus a Service can concurrently handle
  multiple outstanding requests at once.
- It's clearer that Services can likely be cloned
- To share state across clones you generally need Arc<Mutex<_>>
  that means you're not really using the &mut self and could do with a &self

This commit closses issue: hyperium#3040
BREAKING CHANGE: The Service::call function no longer takes a mutable reference to self.
The FnMut trait bound on the service::util::service_fn function and the trait bound
on the impl for the ServiceFn struct were changed from FnMut to Fn
  • Loading branch information
Robin Seitz committed May 12, 2023
1 parent 16a921f commit 60e9f84
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 4 deletions.
10 changes: 9 additions & 1 deletion src/service/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,13 @@ pub trait Service<Request> {
type Future: Future<Output = Result<Self::Response, Self::Error>>;

/// Process the request and return the response asynchronously.
fn call(&mut self, req: Request) -> Self::Future;
/// call takes a &self instead of a mut &self because:
/// - It prepares the way for async fn,
/// since then the future only borrows &self, and thus a Service can concurrently handle
/// multiple outstanding requests at once.
/// - It's clearer that Services can likely be cloned
/// - To share state across clones you generally need Arc<Mutex<_>>
/// that means you're not really using the &mut self and could do with a &self
/// To see the discussion on this see: https://github.com/hyperium/hyper/issues/3040
fn call(&self, req: Request) -> Self::Future;
}
6 changes: 3 additions & 3 deletions src/service/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::{Request, Response};
/// ```
pub fn service_fn<F, R, S>(f: F) -> ServiceFn<F, R>
where
F: FnMut(Request<R>) -> S,
F: Fn(Request<R>) -> S,
S: Future,
{
ServiceFn {
Expand All @@ -46,7 +46,7 @@ pub struct ServiceFn<F, R> {

impl<F, ReqBody, Ret, ResBody, E> Service<Request<ReqBody>> for ServiceFn<F, ReqBody>
where
F: FnMut(Request<ReqBody>) -> Ret,
F: Fn(Request<ReqBody>) -> Ret,
ReqBody: Body,
Ret: Future<Output = Result<Response<ResBody>, E>>,
E: Into<Box<dyn StdError + Send + Sync>>,
Expand All @@ -56,7 +56,7 @@ where
type Error = E;
type Future = Ret;

fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
fn call(&self, req: Request<ReqBody>) -> Self::Future {
(self.f)(req)
}
}
Expand Down

0 comments on commit 60e9f84

Please sign in to comment.