Recently, I found myself returning to a compelling series of blog posts titled
Zero-cost futures in Rust
by Aaron Turon about what would become the foundation of Rust's async ecosyste…
But before that, I should mention that I had to use the browser’s inspector to disable that background color. Light and dark backgrounds are both fine (I have color inversion bindkeyed after all). It’s the ones in the middle like this one that are a no-no.
And while you could exclusively use the runtime and ignore the rest, it is easier and more common to buy into the entire ecosystem.
Stats? User surveys?
I would expect that many users (including myself) actually just use the runtime, directly or indirectly (e.g. via async-global-executor with the tokio feature), while API usage is covered by crates like async-io, async-fs, async-channel, blocking, …etc.
In fact, I would hypothesize that, from an ecosystem adoption POV, tokio’s only killer feature is hyper’s dependence on it. If it wasn’t for that dependence, tokio’s adoption, I would expect, would be much lower. But this is admittedly anecdotal.
Any time we reach for an Arc or a Mutex it’s good idea to stop for a moment and think about the future implications of that decision.
This and the quote above it seem to be Rust intellectuals’ flavor of the month position.
It kind of reminds me of the lowering dependencies’ compile times craze from a few years ago. Stretching the anti-MT-RT narrative to the point of making bad advice like recommending sync channels for an IO task adds to the parallels.
The choice to use Arc or Mutex might be indicative of a design that hasn’t fully embraced the ownership and borrowing principles that Rust emphasizes.
Or maybe you know, using APIs that already existed in std for a reason, as intended!
It’s worth reconsidering if the shared state is genuinely necessary or if there’s an alternative design that could minimize or eliminate the need for shared mutable state.
Generally true. But probably false here.
People reaching for Arc+Mutex/RwLock/… (doesn’t have to be a Mutex) in asyc code are probably aware of alternative designs, but still decide to use Arc+Mutex/RwLock/… when it’s either necessary, or when it actually makes things simpler, and the downsides (performance) are of no measurable relevance, or the alternative design is actually slower (i.e. the multi-threaded runtime is actually helping).
I would consider arguments that talk about “killing all the joy of actually writing Rust” in this context as either intellectual posturing, or simply disingenuous.
As someone who has tried doing multithreaded design with Arc/Mutex, this is a complete nightmare. You constantly get into deadlocks and performance is abysmal, because Mutex is serializing access (so it’s not really async or multithreaded any more).
As someone who has tried doing multithreaded design with Arc/Mutex, this is a complete nightmare.
I myself often use channels. And pass owned data around.
I don’t think anyone argues that Arc+interior-mutation is ideal. But it’s the over-the-top language like “complete nightmare” that some may take issue with.
Note that I again make the distinction between Mutex, and all interior mutation primitives. Because Mutex is indeed a bad choice
in many cases. and over-usage of it may indeed be a signal that we have a developer who’s not comfortable with Rust’s ownership/borrowing semantics.
You constantly get into deadlocks and performance is abysmal, because Mutex is serializing access (so it’s not really async or multithreaded any more).
Same note about Mutex specifically as above.
Avoiding deadlocks can definitely be a challenge, true. But I wouldn’t say it’s often an insurmountable one.
What crate did you use for interior mutability, async-lock, tokio, parking_lot, or just std?
A good topic to chat about.
But before that, I should mention that I had to use the browser’s inspector to disable that background color. Light and dark backgrounds are both fine (I have color inversion bindkeyed after all). It’s the ones in the middle like this one that are a no-no.
Stats? User surveys?
I would expect that many users (including myself) actually just use the runtime, directly or indirectly (e.g. via
async-global-executor
with thetokio
feature), while API usage is covered by crates likeasync-io
,async-fs
,async-channel
,blocking
, …etc.In fact, I would hypothesize that, from an ecosystem adoption POV,
tokio
’s only killer feature ishyper
’s dependence on it. If it wasn’t for that dependence,tokio
’s adoption, I would expect, would be much lower. But this is admittedly anecdotal.This and the quote above it seem to be Rust intellectuals’ flavor of the month position.
It kind of reminds me of the lowering dependencies’ compile times craze from a few years ago. Stretching the anti-MT-RT narrative to the point of making bad advice like recommending sync channels for an IO task adds to the parallels.
Or maybe you know, using APIs that already existed in std for a reason, as intended!
Generally true. But probably false here.
People reaching for
Arc
+Mutex
/RwLock
/… (doesn’t have to be aMutex
) in asyc code are probably aware of alternative designs, but still decide to useArc
+Mutex
/RwLock
/… when it’s either necessary, or when it actually makes things simpler, and the downsides (performance) are of no measurable relevance, or the alternative design is actually slower (i.e. the multi-threaded runtime is actually helping).I would consider arguments that talk about “killing all the joy of actually writing Rust” in this context as either intellectual posturing, or simply disingenuous.
Otherwise, there is not much to disagree with.
As someone who has tried doing multithreaded design with Arc/Mutex, this is a complete nightmare. You constantly get into deadlocks and performance is abysmal, because Mutex is serializing access (so it’s not really async or multithreaded any more).
I myself often use channels. And pass owned data around.
I don’t think anyone argues that Arc+interior-mutation is ideal. But it’s the over-the-top language like “complete nightmare” that some may take issue with.
Note that I again make the distinction between
Mutex
, and all interior mutation primitives. BecauseMutex
is indeed a bad choice in many cases. and over-usage of it may indeed be a signal that we have a developer who’s not comfortable with Rust’s ownership/borrowing semantics.Mutex
specifically as above.async-lock
,tokio
,parking_lot
, or juststd
?I used parking_lot back then.
AFAICT, the current hyper v1 release candidate only depends on tokio for
tokio::sync::{mpsc, oneshot}
(andsync
is the only enabled feature).It’s intended to be runtime-agnostic. See also https://docs.rs/hyper/1.0.0-rc.4/hyper/rt/trait.Executor.html . I agree that its ecosystem is still very tokio-centric.