I read Rocket v0.5 now uses the Tokio runtime to support Async. I know Async can offer great scalability when we have lots of (like hundreds or thousands of) concurrent IO-bound requests. But many web/REST server apps simply don't fall into that category and in such cases, I feel like Async would only complicate stuff. Sorry if that sounds like a dumb question, but with Rocket 0.5+ will I still be able to write a traditional non-async code the same way as before? Does Async-support in Rocket 0.5+ mean that we will only get Async behaviour for async fn
handlers? If so, will the Tokio runtime still play any role in non-async code?
Asked
Active
Viewed 1,056 times
2

at54321
- 8,726
- 26
- 46
-
rocket 0.4 was using a form of async, any true server would, thread, poll or any other method would be use. You NEED async for a server, imagine serving one client by client. Rocker 0.5 just use rust builtin async feature. – Stargateur Oct 10 '21 at 21:38
-
@Stargateur I don't agree Async is required for a server. The "classic" way servers have been implemented is they have a thread pool and when a request comes, the server **dedicates** a thread from that pool to serve the request from start to finish. That way you can still serve multiple requests in parallel. That's how many popular web servers (like Apache, Tomcat, etc.) have been working for so many years. – at54321 Oct 11 '21 at 06:17
-
as I said, that also a form of async. – Stargateur Oct 11 '21 at 13:01
-
Async mainly means non-blocking; a synchronous request cannot be made an async request (without intervention), but an async request may be immediately resolved (in a blocking way) to make it synchronous. I would think they were not mutually exclusive. – Jared Farrish Oct 11 '21 at 16:44
1 Answers
3
Sure you can.
Look at the first examples in the web page:
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
There is no async/await
anywhere. The nicest thing of Rocket5 is that you can choose which views are sync are which are async, simply by making them so, and you can mix them together as you see fit.
For example this will just work:
#[get("/sync")]
fn index1() -> &'static str {
"Hello, sync!"
}
#[get("/async")]
async fn index2() -> &'static str {
"Hello, async!"
}
The Rocket runtime is all async under the hood, but that doesn't need to be exposed to your view handlers at all. When a non-async handler is run, it will be as if Rocket used spawn_blocking()
.

rodrigo
- 94,151
- 12
- 143
- 190
-
Does that mean I could, for example, reliably use Thread Locals in my non-async handlers? – at54321 Oct 11 '21 at 17:24
-
1@at54321: Your non-async handler will be run in a single go: no `await` anywhere, so every time it runs the whole code will execute on the same thread. There is no guarantee that it will be the same thread every time the handler is run, of course, but that was true for rocket-0.4, too. – rodrigo Oct 11 '21 at 18:55
-
Thanks, Rodrigo! That makes sense. I just didn't see those things explicitly mentioned in the docs. – at54321 Oct 11 '21 at 20:27
-
@at54321 For all the hype with async in Rocket 5, the docs and examples are still mostly non-async. I thing it's a great idea: those who need async will find it anyway; those who don't will read a much simpler doc. – rodrigo Oct 12 '21 at 10:07
-
1That makes sense. Generally it's good to have such **option** - to use async when/where you really need it. My only concern is that all that async stuff has made the Rocket crate much bigger (which leads to larger binary, slower build, etc.), but it seems to me most people find such concerns dumb. To me, it would be best if all the async stuff was optional, but perhaps that would be too difficult to implement or they simply don't feel that's important. – at54321 Oct 12 '21 at 11:56