I don't really get these modern async APIs. In languages like Javascript I thought they only made sense because JS interpreters are (historically) single-threaded, so you really have no choice but async to express some concepts. Fine.<p>But in Rust you can just spawn threads, share data through channels or mutexes, use OS-provided async IO primitives to poll file descriptors and do event-driven programming etc...<p>I tried looking into Tokio a little while ago and I found that it led to some incredibly complicated, abstracted, hard to think about code for stuff I usually implement (IMO) much more simply with a basic event loop and non-blocking IO for instance.<p>I'm sure async can get the upper hand when you have a huge number of very small tasks running concurrently because that's generally where OS-driven parallelism tends to suffer but is it such a common scenario? That sounds like premature optimization in many situations IMO. Unless you actually think that async code is more expressive and easy to read and write than basic event loops, but then you must be a lot smarter than I am because I have to take an aspirin every time I need to dig into async-heavy code.<p>I guess I'm trying to understand if it's me who's missing something, or if it's web-oriented developers who are trying to bring their favourite type of proverbial hammer to system development.
As someone who has criticized Rust for the small standard lib and lack of stability in the ecosystem I'm very, very happy for this. This is one of the biggest milestones for Rust. Rust itself is great enough. The lack of a de facto async runtime and libs for your standard networking needs were a real barrier for non-enthusiasts environments. It will help its adoption in general purpose business apps, I guess and hope.
Can someone explain to a non-rustacean what Tokio introduces that's not part of Rust? It looks like Rust provides the async/await semantics, so I'm guessing this is an event loop and dispatching system?
One of the issues I have with the rust async story is that colored functions require (at least the way they’re handled in rust and similar languages) a separate standard library (Microsoft really outdid themselves providing a synchronous and asynchronous version of the BCL when they shipped async support, but that was also largely made possible by the fact that the underlying OS APIs were all fairly asynchronous at the lowest levels <i>and</i> had that asynchronocity exposed/available all the way through the BCL for C# devs already).<p>One problem with this is that an api like tokio’s might appear to be asynchronous but in reality portions of it are “just” synchronous API calls marshaled to a thread pool - i.e. none of the real benefits of async for now, but positioned so that the library can be switched over to real async code and automatically take all the consumers with “it in the future.”<p>I’m glad to hear mention of io_uring because it means that IOCP on Windows might get some love. For those that don’t know, on Linux there is^H^H was really no such thing as properly async file system access (eg libc faked it in a similar fashion for aio) so libraries like mio didn’t bother with true async for non-network parts of the library (and also partially because the biggest motivation for async development was the web world which doesn’t particularly care about asynchronously listing the contents of a directory or writing a “highest” performance backup product) - even though at least some platforms (like Windows) had very compelling async options available across the board.
They mention working on using io_uring for filesystem calls for 2021. I wonder if there will be an option to use io_uring (instead of epoll) for networking calls as well? Handling network packets and events completely in userspace should allow for lower latency due to no more context switches to and from the Kernel, right?
Huge thanks to all the contributors! I've been using Tokio in a few projects and it has been a very good experience. Also thank you all for the welcoming community. I once posted on Tokio's Github about a quirky (in my eyes) behavior of a particular edge case and got an answer almost in real time. This really makes Tokio a kind of a project where I could see myself contributing if an appropriate opportunity arises.<p>Thanks again! Looking forward to all the good things still in the pipeline!
The changelog can be found here: <a href="https://github.com/tokio-rs/tokio/releases/tag/tokio-1.0.0" rel="nofollow">https://github.com/tokio-rs/tokio/releases/tag/tokio-1.0.0</a>
I'm hopeful that this leads to some focus on the ergonomics of "waiting for async things from sync code". Lots of "handlers" in the universe have synchronous interfaces, so if you want to implement them you end up needing to poll/wait on async from a regular function. I swear that every time I poke at Rust, I seem to find some way to cut my fingers...<p>My specific example is writing a fuse handler (now with cberner/fuser formerly zargony/rust-fuse) for GCS/S3. If you want to use make any async requests (like via hyper), you currently have to roll your own poller, like reqwest does in blocking mode [1].<p>The rust async/.await primer [2] offers the reader the seemingly helpful futures::executor::block_on, but basically no two executors can interact (and for good reason!). As others highlight, the ecosystem seems like it's going to end up standardizing on tokio (and/or some flavor thereof) and that hopefully now that it's 1.0, we can have stable enough deps for a while :).<p>[1] <a href="https://github.com/seanmonstar/reqwest/blob/5ee4fe5ab64a2e3d81efb9540cb9bdb98b8d6938/src/blocking/wait.rs#L10" rel="nofollow">https://github.com/seanmonstar/reqwest/blob/5ee4fe5ab64a2e3d...</a><p>[2] <a href="https://rust-lang.github.io/async-book/01_getting_started/04_async_await_primer.html" rel="nofollow">https://rust-lang.github.io/async-book/01_getting_started/04...</a>
Today also saw the release of Hyper 0.14, the HTTP client built on top of Tokio [0]<p>[0]: <a href="https://news.ycombinator.com/item?id=25521217" rel="nofollow">https://news.ycombinator.com/item?id=25521217</a>
Congratulations on 1.0! Tokio and the ecosystem surrounding it (tracing, hyper, prost, tower) are incredibly well thought out and a pleasure to use for building fast performant services with solid latencies.
Always found these APIs a little hard to work with. For instance, if I tried to use `actix-web`, then using `reqwest` and `tokio` felt like pulling teeth.<p>If anyone's got minimal code lining up a web framework (any one, not stuck to actix) with some reqwest, I'd be thankful to look over it. Just some trivial stuff so I can add an API gateway that proxies a specific API.
Congrats! I've fallen off Rust due to pivoting at work plus trying other languages but I'm intrigued again by Tokio's announcement. I'll be trying out your tutorial soon!
It is unfortunate, that libraries have to be coded against specific runtime and not generically. There is tokio and there is smol (likely discontinued, since author left rust), maybe other runtimes will emerge, but whole ecosystem is already tied to tokio.
I wonder whether there is any ongoing effort to unify the ecosystem between different runtimes. Specially considering that Tokio and futures (by extension async-std) implement their own Async* traits, it seems that it becomes even harder to write runtime agnostic libraries. It would be nice if these fundamental traits were part of rust std library.
It's getting close to the point where I can't make my "semver just means prefixing your version number with `0.`" joke anymore. :<<p>Congrats to the tokio team + contributors. <:)
Cool stuff. There seems to be some cool improvement every several months.<p>I'm excited for GATs to land so we can have true async trait methods. The async story in Rust has come a long way, but there's still a lot to be improved.
There seems to be some time loop with network application concurrency approaches. I began my career re-writing servers that had a non-blocking socket model with a state machine to use threads, so we could understand and maintain the code now that OS vendors had come around to supporting threading widely. Fast forward a few decades and the world is teeming with smart people who seem to think it's a good idea to go the other way..
This is awesome, congrats on the 1.0!<p>As a new rustacean it was really difficult to try and use the the async/await syntax with horde of adapters required for tokio 0.1/0.2. I ended up trying out async-std too, but the move to smol had its own issues and I lost interest.<p>A 1.0 release with stability commitments is exactly what I need to get back into experimenting with Rust.
I see a lot of hate for what amounts to user controlled and scheduled tasks. Do people understand that async/await is effectively user land task scheduling, which for any high performance networking app is of vital importance. Consider cassandra versus scylladb
> Also, Tokio would not have been possible without Aaron Turon's and Alex Crichton's early involvement.<p>This feels like a slap in the face for some reason.<p>Aaron Turon is an extremely talented individual (their PhD thesis was a landmark contributionn). They are super kind and one of the nicest human beings I've ever met. They led the Rust Project until their involvement with Tokio caused them to drop off from Tech.<p>Alex Crichton is an extremely talented, kind, and hyperproductive individual, who after their involvement with Tokio dropped all async/await work and luckily "refocused" on WebAssembly.<p>If one is going to recap the road towards Tokio 1.0 and mention all the people that have left the Rust async ecosystem or Rust all together, you might as well spell things out.
I find the domain amusing: <a href="https://en.m.wikipedia.org/wiki/Srbija_do_Tokija" rel="nofollow">https://en.m.wikipedia.org/wiki/Srbija_do_Tokija</a>
It irks me that the "async runtime" isn't simply part of the rust runtime. Making it be a separate library simply increases the likelihood of having to deal with libraries expecting different version, or even different async runtimes entirely.
I really like writing rust, however not having the async runtime be a part of std has hurt the language in my opinion.<p>Crate consumers have to consider which async lib a crate is using leads to a lot of annoying gotchas that can really confuse less experienced rust devs.<p>I'm hoping tokio becomes the default and eventually gets merged into std, it really is the best async implementation.
The first two paragraphs have a lot of guarantees. About stability of version 1.0, length of support for version 1.0 and how long until version 2.0 (at least). "We<p>"we are committing to providing a stable foundation..."<p>I am curious: Who is "we"? I have no priors, I really have no idea.