Live data from Hacker News

Maybe Rust isn’t a good tool for massively concurrent, userspace software

bitbashing.io

31–40 of 624 posts

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#31
post #11
post #2

> Used pervasively, Arc gives you the world’s worst garbage collector. Like a GC, the lifetime of objects and the resources they represent (memory, files, sockets) is unknowable. But you take this loss without the wins you’d get from an actual GC! The lifetime of an Arc isn’t unknowable, it’s determined by where and how you hold it. I think maybe the disconnect in this article is that the author is coming at Rust and…

> The lifetime of an Arc isn’t unknowable, it’s determined by where and how you hold it. In the same sense that the lifetime of an object in a GC'd system has a lower bound of, "as long as it's referenced", sure. But that's nearly the opposite of what the borrow checker tries to do by statically bounding objects, at compile time. > maybe the disconnect in this article is that the author is coming at Rust and trying t…

Honestly, the biggest stumbling block for rust and async is the notion of memory pinning.

Rust will do a lot of invisible memory relocations under the covers. Which can work great in single threaded contexts. However, once you start talking about threading those invisible memory moves are a hazard. The moment shared memory comes into play everything just gets a whole lot harder with the rust async story.

Contrast that with a language like java or go. It's true that the compiler won't catch you when 2 threads access the same shared memory, but at the same time the mental burden around "Where is this in memory, how do I make sure it deallocates correctly, etc" just evaporates. A whole host of complex types are erased and the language simply cleans up stuff when nothing references it.

To me, it seems like GCs simply make a language better for concurrency. They generally solve a complex problem.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#32
post #16

I find myself in this weird corner when it comes to async rust. The guy's got a point in that doing a bunch of Arc, RwLock, and general sharing of state is going to get messy. Especially once you are sprinkling 'static all over the place, it infects everything, much like colored functions. I did this whole thing once back when I was starting off where I would Arc stuff, and try to be smart about borrow lifetimes. Tot…

Hoare Was Right. (But if you're only firing up a few tasks, why not just use threads? To get a nice wrapper around an I/O event loop?)

Exactly. People are too afraid of using threads these days for some perceived cargo-cult scalability reasons. My rule of thumb is just to use threads if the total number of threads per process won't exceed 1000.

(This is assuming you are already switching to communicating using channels or similar abstraction.)

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#33
post #24

I find myself in this weird corner when it comes to async rust. The guy's got a point in that doing a bunch of Arc, RwLock, and general sharing of state is going to get messy. Especially once you are sprinkling 'static all over the place, it infects everything, much like colored functions. I did this whole thing once back when I was starting off where I would Arc stuff, and try to be smart about borrow lifetimes. Tot…

I really like the message passing paradigm. And languages like Erlang have shown that its an excellent choice... for distributed systems. But writing code like that is a very diffferent experience from, say, async JavaScript, which feels more like writing synchronous code with green threads (except you have to deal with function coloring as well). I believe people will try to write code in a way that is already famil…

Go also uses goroutines and channels to facilitate message passing, or as they describe it, "sharing memory by communicating."

I imagine Rust to be a language far more similar to Go, in both use cases and functionality, than JS.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#34
post #22

Async Everything is a bad language. Async/await was a terrible idea for fixing JavaScript's lack of proper blocked threading that is currently being bolted onto every language. It splits every language and every library-ecosystem in half and will cause pains for many years to come. Everyone who worked with multi-threading outside of JavaScript knows that using actors/communicating sequential processes is the best way…

> Async/await was a terrible idea for fixing JavaScript's lack of proper blocked threading that is currently being bolted onto every language.

As fun as it is to hate on JavaScript, it's really interesting to go back and watch Ryan Dahl's talk introducing Node.js to the world (https://www.youtube.com/watch?v=EeYvFl7li9E). He's pretty ambivalent about it being JavaScript. His main goal was to find an abstraction around the epoll() I/O event loop that didn't make him want to tear his eyes out, and he tried a bunch of other stuff first.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#35
post #26

Now, I think async is bad syntactic sugar that hides what's really going on under the surface. And I rail against it all the time. Especially the way dropping in async contaminates code bases by building tendrils across call-sites all through the application. ... But the tools that have been built around it are very useful and there's some good stuff there. I have some quibbles with this article: "Rust comes at this…

> It allows for that This is like saying C++ allows for templates, and theres a big community around it. Sure, but its the entire community.

If you're a web facing developer and looking at web services, then I guess you could think this about Rust.

Believe it or not, there's other types of things being built in Rust. Systems work, which I think Rust is more appropriate for.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#36

I find myself in this weird corner when it comes to async rust. The guy's got a point in that doing a bunch of Arc, RwLock, and general sharing of state is going to get messy. Especially once you are sprinkling 'static all over the place, it infects everything, much like colored functions. I did this whole thing once back when I was starting off where I would Arc stuff, and try to be smart about borrow lifetimes. Tot…

this is what Go got right like 10 years ago

In the sense that green threads are easier, sure.

But green threads were not and are not the right solution for Rust, so it's kind of beside the point. Async Rust is difficult, but it will eventually be possible to use Async Rust inside the Linux kernel, which is something you can't do with the Go approach.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#37
post #2

> Used pervasively, Arc gives you the world’s worst garbage collector. Like a GC, the lifetime of objects and the resources they represent (memory, files, sockets) is unknowable. But you take this loss without the wins you’d get from an actual GC! The lifetime of an Arc isn’t unknowable, it’s determined by where and how you hold it. I think maybe the disconnect in this article is that the author is coming at Rust and…

Reference counting is a type of GC [0]. Just not a very good one in many cases.

I think it's a fair assumption to say that the author is aware of what Arcs are and how they work. I believe their point is more so that because of how async works in Rust, users have to reach for Arc over normal RAII far more often than in sync code. So at a certain point, if you have a program where 90% of objects are refcounted, you might as well use a tracing GC and not have the overhead of many small heap allocations/frees plus atomic ops.

Perhaps there are in fact ways around Arc-ing things for the author's use cases. But in my (limited) experience with Rust async I've definitely run into things like this, and plenty of example code out there seems to do the same thing [1].

For what it's worth, I've definitely wondered whether a real tracing GC (e.g. [2]) could meaningfully speed up many common async applications like HTTP servers. I'd assume that other async use cases like embedded state machines would likely have pretty different performance characteristics, though.

[0] https://en.wikipedia.org/wiki/Garbage_collection_(computer_s...

[1] https://tokio.rs/tokio/tutorial/shared-state

[2] https://manishearth.github.io/blog/2015/09/01/designing-a-gc...

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#38
I have been using "async/await is bad, use {feature name[0]}" as a litmus test for people who are generally bad at programming, especially so at concurrent flavour of such.

Sure, Rust is certainly verbose and very strict how the ownership rules apply in the context of async, but this is a hard constraint of its memory safety model. We could probably do better while retaining all performance but this is by far one of the best implementations. Another example of nice to use async/await is C# which trades performance/memory (state has to be boxed if it is to live across continuations) for convenience (you just write it naturally without worrying about underlying behavior).

There is a reason Rust toyed with "green threads" at its inception but decided against such. The only popular languages of today that do these are Go and Java (which basically forced to do this because you can't go async without introducing the feature early in the lifecycle of the language, and the authors of project Loom are simply wrong with their excuses why this is superior to async/await).

Async/await is here to stay and is the right abstraction, git good, and it's not even difficult to use anyway.

[0] where feature name is green threads, not doing concurrency at all, doing it manually, etc.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#39
> At this scale, threads won’t cut it—while they’re pretty cheap, fire up a thread per connection and your computer will grind to a halt.

Maybe in the 2000's but I feel this reasoning is no longer valid in 2023 and should be put to rest.

10k problem.. Wouldn't modern computing not work if my Linux box couldn't spin up 10k threads? Htop says I'm currently at 4,000 threads on an 8 core machine.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#40

I find myself in this weird corner when it comes to async rust. The guy's got a point in that doing a bunch of Arc, RwLock, and general sharing of state is going to get messy. Especially once you are sprinkling 'static all over the place, it infects everything, much like colored functions. I did this whole thing once back when I was starting off where I would Arc stuff, and try to be smart about borrow lifetimes. Tot…

> If there's a large object that more than one task needs, either you put it in a task that sends messages containing the relevant query result, or you let each task construct its own copy from the stream of messages.

When you can guarantee sole ownership, why not put that exclusive pointer in the message? I’d think that this sort of compile-time lock would be an important advantage for the type system. (I think some VMs actually do this sort of thing dynamically, but I can’t quite remember where I read about it.)

On a multiprocessor, there’s of course a balance to be determined between the overhead of shuffling the object’s data back and forth between CPUs and the overhead of serializing and shuffling the queries and responses to the object’s owning thread. But I don’t think the latter approach always wins, does it? At least I can’t tell why it obviously should.

Post reply on HN