httprouter-rs icon indicating copy to clipboard operation
httprouter-rs copied to clipboard

Remove `Sync` bounds

Open malobre opened this issue 2 years ago • 2 comments

Currently all route handlers needs to be Send, Sync and 'static, the default hyper Executor only requires Send and 'static bounds (see this line).

The Sync bound is currently needed because RouterService holds an Arc<Router> which only implements Send if the underlying type is both Send AND Sync.

A workaround would be to wrap the router in a Mutex: Arc<Mutex<Router>>. Since Mutex implements Send and Sync for all types that are Send this should removes the need for all Sync bounds.

However this would prevent the user from wrapping a Router in an Arc themself:

// `router` won't be `Send` because of `Arc` `Sync` requirements
let router = Arc::new(Router::default());

let make_svc = make_service_fn(move |_| {
     let router = router.clone();
     async move {
         Ok::<_, Infallible>(service_fn(move |req: Request<Body>| {
             let router = router.clone();
             async move { router.serve(req).await }
         }))
     }
 });

 let server = Server::bind(&([127, 0, 0, 1], 3000).into())
     .serve(make_svc)
     .await;

An alternative would be to wrap all the inner fields of Router in a struct, wrapped in a Mutex:

struct Router {
    inner: Mutex<RouterInner>
}

struct RouterInner {
    /* -- snip --*/
}

There may be other solutions, but I'm not aware of them ATM.

malobre avatar Jul 10 '21 18:07 malobre