async fn main() {
let addr = SocketAddr::from(([0,0,0,0], 3000));
// My global state
let state = Arc::new(RequestState { foo: 321 });
// How can I make some sanity this onion1, onion2, onion3, onion4? Is it possible?
let make_svc = make_service_fn(|_| {
let onion1 = Arc::clone(&state);
async move {
Ok::<_, Infallible>(service_fn(move |req: Request<Body>| {
let onion2 = Arc::clone(&onion1);
async move {
handle_request(&*onion2, req).await
}
}))
}
});
let server = Server::bind(&addr).serve(make_svc);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}
make_service_fn is called for each connection you receive.
service_fn is called for each request in that connection. Note that with the Connection: keep-alive header, you can have several requests in one connection.
What happens now is:
When a new connection occurs, the outer closure is called and it makes a clone of the state, which it gives to the closure in service_fn (through two moves). It has to clone it, because this may happen many times, so it can't give it's own copy away.
When the closure in service_fn is called, it needs to clone it again, because the async block it returns must not borrow from the one copy stored in the service_fn closure — so another clone must be made to be owned by that async block it returns. Note that this closure may also be called many times (once per request in current connection), which is why it cannot give away it's own copy.
This is why two clones are necessary. And as you can see in the snippet above, it's possible to do with only two clones.