Hacker News new | past | comments | ask | show | jobs | submit login

The main reason to use async in rust is that seemingly every network library uses async.

Yes. I was calling that "async contamination" a few years back when that trend started. There's a strong lobby for doing web backend stuff in Rust, and they want it to work like Javascript.

On the thread side, deadlocks can be a problem. You don't get any help from the language in keeping your lock hierarchy consistent. There are systems that can detect at compile time that one path locks A before B, and another path locks B before A. Rust needs such analysis.

It turns out that the built in mutexes are not "fair". Actually, they're worse than not fair. If you have two thread loops that do "get item, lock, handle item, unlock", one of them can be starved out completely. This happens even though there's a moment when the mutex is unlocked and something is waiting on it. It's a consequence of an optimization in std::sync::Mutex for the fast case.

The "parking_lot" crate has fair mutexes, but it doesn't have panic poisoning and is not unwind safe, so catching failed threads to get a clean shutdown is hard. This is an issue for GUI programs, because failing to catch panics means the user experience of a failure is that the window closes with no message.




"On the thread side, deadlocks can be a problem. You don't get any help from the language in keeping your lock hierarchy consistent."

The 98% solution to this problem is to dodge it entirely. Communicate with things like channels, mailboxes, and actors, or other higher-level primitives. This is how Go programs hold together in general despite not even having as much support as Rust does for this sort of analysis.

The rule I've given to my teams is, never take more than one lock. As soon as you think you need to, move to an actor-ownen-resource or something. The "real" rule (as I'm sure you know, but for others) with multiple locks is "always take them in the same deterministic order" (and even that's a summary, it really also ought to discuss how only mutexes that can ever be taken at the same time have to be considered in order, and heck for all I know it gets complicated beyond that too; at this point I bug out entirely) but this is, in my opinion, the true source of "thread hell" as written about in the 90s. I don't think it was threading that was intrinsically the problem; yes, threads are more complicated than a single thread, but they're managable with some reasonable guard rails. What was insane was trying to do everything with locks.

In theory, this rule breaks down at some point because of some transactionality need or another; in practice, I've gotten very far with it between a combination of being able to move transactionality into a single actor in the program or offload it to a transactionally-safe external DB. For which, much thanks to the wizards who program those, test those, and make them just a primitive I can dip into when I need it. Life savers, those folk.


Yes, I might have been better off with an actor model. I'm writing a high-performance metaverse client, which has both the problems of a MMO game and of a web browser. Must maintain the frame rate, while content you don't control floods in.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: