I'm a strong believer in structured concurrency over async.
That said, I do not know if there would be an easier way to implement the state machine in the article using structured concurrency over async. Maybe that is actually one place where async would be better.
I need to look into that.
However, for those in the comments arguing that async is better for I/O-bound stuff, I heavily disagree.
I implemented a multiplexer system. You can start any number of operations you want and then multiplex them. This blocks until one operation is done, yes, but hey, you have threads, so use another to do something else if you need.
But this multiplexer allows me to decide what function gets called for each type of task that finishes. This means that the caller still controls what to do then the "future" completes.
So it's equivalent to async, but it's still synchronous. Nice.
I can have it multiplex on multiple types of things too. I actually haven't implemented asynchronous I/O with it yet; I mostly use it to multiplex on child processes.
So I agree with one of the top-level comments: async is a hype. There are better ways for most use cases.
In the broad use case where you have an IO-bound server, how is this solution better than async? It sounds like your non-async solution was to reimplement async, which shows the value of the feature.
In Rust (which is the async/await system mentioned in the article), futures don't start until they're polled, so doing the pattern you describe wouldn't even have the ordering part you mention (unless you wanted it to, in which case you could use something like Tokio's `spawn`).
That's technically something the runtime implementation can choose, but for Tokio, the most common runtime, the sibling comment is correct that the only way to avoid having to explicitly define it is to use an annotation on the main function (which just generates the call to instantiate the runtime via a macro).
That said, I do not know if there would be an easier way to implement the state machine in the article using structured concurrency over async. Maybe that is actually one place where async would be better.
I need to look into that.
However, for those in the comments arguing that async is better for I/O-bound stuff, I heavily disagree.
I implemented a multiplexer system. You can start any number of operations you want and then multiplex them. This blocks until one operation is done, yes, but hey, you have threads, so use another to do something else if you need.
But this multiplexer allows me to decide what function gets called for each type of task that finishes. This means that the caller still controls what to do then the "future" completes.
So it's equivalent to async, but it's still synchronous. Nice.
I can have it multiplex on multiple types of things too. I actually haven't implemented asynchronous I/O with it yet; I mostly use it to multiplex on child processes.
So I agree with one of the top-level comments: async is a hype. There are better ways for most use cases.