There is actually already a tutorial at this level: Tokio has its ‘async in depth’ tutorial [1] that walks you through building a toy runtime and using it to run a future.
Not a complaint — you can never have too many tutorials, unless they're about monads — but just a pointer in case you hadn't seen it :)
It looks like rust async creates state machines similar to how Kotlin does it with so-called Continuations.
The continuation model is the standard model of async programming and still perhaps the nicest semantically. Rust's big innovation is that futures are polled from the top, i.e. (potentially) advanced in an idempotent way whenever any of their relevant resources progresses, which is nicer for resource-conscious programming because it doesn't require that you capture the stack. It adds complexity over the continuation model from the programmer's point of view, but opens up async programming to a wider range of contexts in a way that is genuinely novel.
No, I haven't asked anyone to upvote or comment. It was posted 2-3 days ago, there were no upvotes. And I was feeling concerned. (I am doing this full time and getting on top of HN for my own work was a dream). I had written articles on bevy and also posted on HN (in last 6 months). But they hardly got any traction on HN.
Not sure what happened today, I saw traffic from HN and was surprised to see this on #8.
I also noticed few comments looked LLM generated (they got deleted), but I am not sure why someone would do it, I mean the incentive.
Async in an embedded context is actually really nice, too. You can have high level "send this thing over SPI, receive this data from USB" futures and they will run (ideally via DMA) and your CPU can go to sleep, only waking up when interrupts fire from the hardware peripherals you were using.
The rust flow is so much more natural to me.
If you hate garbage collection pauses (which most Rust users do) then don't use async.
Sure, if you need to run 20k connections then use async. But the fact of the matter is that the vast majority of software is not going to take on 20k connections. Those people (i.e the majority of software devs) should use threads, because they are much easier to reason about and work with.
> Whereas async simply locks the CPUWhereas async simply locks the CPU
This is also completely nonsense, context switching behavior is OS dependent and your average general purpose kernel is not cooperative. You will run for your allotted quanta or reschedule when you run out of coroutines that can execute without waiting for resources.
True, but if all you are using is async, then you're basically back at Windows 3.1 cooperative multitasking, except now within a Rust program.
As other commenters have pointed out, cooperative multitasking is actually a great fit for I/O bound code.
It's just doing a loop and a call to poll(), that's it.
It's way way way less expensive than using threads. Of course you must give control to your main loop every once in a while, so if you have a long computation you either create a thread or split it and return control to your main loop.
It's how all GUI programming has always been done.
For other things, async task (or green thread, whatevs) per connection is a very nice model that you can't do with thread per connection because I don't think OSes are happy to gave hundreds of thousands of threads.
I don’t think I ever seem this patterns, What I’ve seen is either a thread pool for tasks (what essentially async is), or dedicated threads for each parts of the processing (a thread for the UI, and a thread for some background services like playing music).
this doesn't really contradict with
> async task (or green thread, whatevs) per connection
The async tasks will probably run on a thread pool (e.g. in tokio).