-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Need to document how to clone clonable objects like Arc<> into a service_fn() in Hyper #2446
Comments
I have been in the exact same situation several times and I agree the errors messages aren't great. I'll try and work on adding a better example to the server docs. For your particular example I would probably write it like this: let service = service.clone();
let hyper_service = service_fn(move |req: Request<Body>| web_handler(service.clone(), req));
let make_service = make_service_fn(move |_| {
let hyper_service = hyper_service.clone();
async move { Ok::<_, Infallible>(hyper_service.clone()) }
});
let server = builder.serve(make_service).with_graceful_shutdown(async {
let _ = shutdown_rx.await;
});
let server_join_handle = tokio::task::spawn(server); I haven't actually tested this but I believe it should compile. Its not a big improvement but might be slightly easier to read. I'm also working on a fix for #2154 which will improve the ergonomics quite a bit. |
It can sometimes be tricky to discover where to use `move` closures, `async move {}`, and `.clone()` when creating a server. This adds a slightly more bigger example that will hopefully help some. Fixes #2446
It can sometimes be tricky to discover where to use `move` closures, `async move {}`, and `.clone()` when creating a server. This adds a slightly more bigger example that will hopefully help some. Fixes #2446
It can sometimes be tricky to discover where to use `move` closures, `async move {}`, and `.clone()` when creating a server. This adds a slightly more bigger example that will hopefully help some. Fixes hyperium#2446
In the existing example code, the way to get your own clonable objects like Arc<> into a Hyper service is extremely non-obvious. It took me hours to figure it out. Sure more experience Rust users might find it easier, but it'd be helpful to newer Rust programmers to show and explain such a common thing. Also doesn't help that async is newer in Rust and documentation for how to do common things in async is still somewhat sparse.
Here's how I did it:
NOTE:
service
is something from my code, not the hyper "service."The "service" is an Arc<> containing a Sync+Send object. If you do the obvious thing and use simple "async move" closures, you get some rather cryptic errors about inability to move blah blah blah. You instead have to give it conventional function closures that clone the object and then return an async closure with a copy per async closure.
This way clone() happens for each web request and you get the expected behavior of Arc<> in the context of asynchronous "pseudo-threads." (Async tasks are not threads but can be thought of as almost threads re: ownership and reference counting semantics.)
The text was updated successfully, but these errors were encountered: