1. 19
  1. 4

    This is one of my biggest gripes with rust. I wish the author(s) would also consider adding an executor in std as a possibility (merging smol for example?)

    1. 4

      Making one executor the “blessed official” one would be a little divisive, especially as different ones have different design goals. The other reply asking why not another executor is a perfect example of this.

      One of rust’s official design goals was to avoid the ossification of the standard library, by leaving big things like this out of it. We are definitely suffering the unfortunate consequence of that: fragmentation in areas where interop is hard.

      Standardizing on an interface and keeping that in the stdlib would ideally let us have the best of both worlds.

      1. 3

        Making one executor the “blessed official” one would be a little divisive, especially as different ones have different design goals

        It makes sense, given that one of Rust’s foundational pillars is “abstraction without overhead”. Any concrete executor is unavoidably specialized to particular class(es) of workload, and will unavoidably impose overhead for others. That’s inherent complexity to the domain.

        Following from that, and alas, I’m afraid that

        Standardizing on an interface and keeping that in the stdlib would ideally let us have the best of both worlds.

        is essentially impossible. I think any abstraction sufficiently general to support even the existing set of implementations will necessarily prevent the end-to-end optimizations that make each of those implementations suitable for their use cases. Exectors aren’t, like, JSON parsers, or regexp engines; effective parallelism requires deep integration with the full language stack.

      2. 4

        If smol was merged, then many Rust projects would still replace it with tokio. You’d still have fragmentation, dependencies, and keep explaining to users unhappy with async Rust’s speed/features that std is not the best option. Or if std merged tokio instead, then you’d have a similar talk with microcontroller people who say Rust’s async is too bloated. In browser WASM you have no choice but to use browser’s runtime. In GUI applications you’d rather use the GUI event loop as your executor, not a custom runtime.

        One-size-fits-all runtime together with std’s promise of never making any breaking changes ever, is a recipe for being stuck with a deprecated sub-par solution.

        1. 1

          . . . a recipe for being stuck with a deprecated sub-par solution.

          For some workloads, sure. Is there a runtime that would best serve the needs of the majority of Rust users? Honest question!

          1. 6

            For most users evidently tokio works fine.

            But keep in mind that Rust in general targets a minority of users not served well by more popular languages — for most programs using a garbage collector is fine. So in this case I’d also be concerned that even though for most users tokio is fine, it’d leave out an important minority that really really needs something else.

            1. 2

              (FWIW: I’m one of the original project members of async-std)

              I would say async-std, smol and tokio all serve the needs of the majority. The reason for that is that most users are interested in the execution model, but are not using it that strongly that all of the small details matter.

              From the async-std side, we do see users picking async-std over tokio though for performance profile reasons (tokio is better tuned for latency, async-std better to throughput - note that this is reported on their workload).

          2. 1

            I hear really great things about smol but was also wondering why not async-std? That also seems really capable, no?

            1. 2

              From what I understand async-std and smol both use async-executor. I believe async-std is effectively a wrapper around async-io and blocking, which smol encourages you to use directly. Both were developed by the same person.

          3. 1

            I don’t use async Rust, but I’ve seen complaints that the lang-level async support prematurely standardized on the “readiness-based” async model (e.g. epoll/kqueue), while the rest of the world seems to be moving toward the “completion-based” async model (e.g. IOCP/io_uring). What do actual Rust async users (say who might want to use underlying OS support in IOCP/io_uring) think of this?