Live data from Hacker News

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

bitbashing.io

181–190 of 624 posts

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

#181

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 find the criticisms a little strange - async doesn’t imply multithreaded, and you don’t need to annotate everything shared with magic keywords if you’re async within the same thread because there’s no sharing. Only one future at a time is running on the thread and they’re within the same context. When moving between threads I do what you suggest here and use channels to send signals rather than having a lot of shar…

> async doesn’t imply multithreaded

Async the keyword doesn’t, but Tokio forces all of your async functions to be multi thread safe. And at the moment, tokio is almost exclusively the only async runtime used today. 95% of async libraries only support tokio. So you’re basically forced to write multi thread safe code even if you’d benefit more from a single thread event loop.

Rust async’s set up is horrid and I wish the community would pivot away to something else like Project Loom.

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

#182
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…

> 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.

These are not the same.

The problem with GC'd systems is that you don't know when the GC will run and eat up your cpu cycles. It is impossible to determine when the memory will actually be freed in such systems. With ARC, you know exactly when you will release your last reference and that's when the resource is freed up.

In terms of performance, ARC offers massive benefits because the memory that's being dereferenced is already in the cache. It's hard to understate how big of a deal this is. There's a reason people like ARC and stay away from GC when performance actually begins to matter. :)

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

#183
post #168
post #90

Earlier quoted context omitted.

And in the end, almost everything ends up using Mutex, RWMutex, WaitGroup, Once, and some channels that exist only to ever be closed (like Context.Done), and only if you need to select around them. It's great, but message passing it is not.

If you choose to use Mutex, that's on you. Rust gives you channels (both synchronous blocking channels and async channels), and they work great, there is nothing stopping you from using them.

I'm pretty sure the gp was talking about Go Mutex, not Rust Mutex.

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

#184

Yes, async is effectively a much harder version of Rust, and it's regrettable how it's been shoved down the throats of everyone, while only 1% of projects using it really need it. Hover, async is also amazing in these 1% of cases when it's useful. If you have a service that handles massive amounts of network calls at the core (think linkerd, nginx, etc.), or you want to have a massive amount of lightweight tasks in y…

The argument here is that Rust chose to implement coroutines the wrong way. It went the route of stackless coroutines that need async/await and colored functions. This creates all the friction the article laments over. But it also praises Go for its implementation, which is also based on a coroutine of a different kind. Stackful coroutines, which do not have any of these problems. Rust considered using those (and, at…

> because stackfull coroutine requires a runtime that preempts coroutines

I've used stackful coroutines many times in many codebases. It never required or used a runtime or preemption. I'm not sure why having a runtime that preempts them would even be useful, since it defeats the reason most people use stackful coroutines in the first place.

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

#185

Earlier quoted context omitted.

> Rust considered using those (and, at first, that was the project's direction). Ultimately, they went to the stackless operation model because stackfull coroutine requires a runtime that preempts coroutines (to do essentially what the kernel does with threads). This was deemed too expensive. Stackful coroutines don't require a preemptive runtime. I certainly hope that we didn't end up with colored functions in Rust…

They often implement soft preemption. Tokio and others like Glommio do. Usually, it's based on interrupts. The runtime schedules a timer to fire an interrupt, and some code is injected into the interrupt handler. This is used to keep track of task runtime quotas so they can yield as soon as possible afterward. This is the same technique used in Go and many others for preemption. If you don't add this, futures that do…

> You are right that it is not strictly necessary, but in practice, it is so helpful as a guard against the yielding problem that it's ubiquitous.

This is honestly shocking to hear. I would think that if people had bugs in their programs they would want them to fail loudly so they can be fixed.

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

#186

> You might say this isn’t a fair comparison—after all, those languages hide the difference between blocking and non-blocking code behind fat runtimes, and lifetimes are handwaved with garbage collection. But that’s exactly the point! These are pure wins when we’re doing this sort of programming. Until all the work you're trying to push is generating so many allocations that your GC goes to shit once every two minute…

Go's GC is hardly state of the art.

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

#187

Earlier quoted context omitted.

Is there any reason to use async when your platform supports virtual threads? I ask as someone who uses java and is about to rewrite a bunch of code to be able to chuck the entire async paradigm into the trash can and use a blocking model but on virtual threads where blocking is ok.

Virtual threads or green threads, etc., are all names for the same thing: stackful coroutines. I would say yes! If your language/platform/runtime supports them, that should definitely be your starting point.

> that should definitely be your starting point.

Could you expand a bit? Why?

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

#188
post #175

Earlier quoted context omitted.

Why does Smalltalk constantly get credit for being true OOP? Simula was doing OOP long before Smalltalk. Most languages choose Simula style OOP, and reject the things that make Smalltalk different. If you say Smalltalk is better OOP I might agree, but calling it "true" is not correct.

Alan Kay is generally credited with coming up with the term "object-oriented", so for better or for worse, many people defer to his definition and his embodiment of ideas when looking for a strict definition of the term.

Honestly, though, that’s like crediting William Burroughs with Blade Runner.

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

#189

Earlier quoted context omitted.

The argument here is that Rust chose to implement coroutines the wrong way. It went the route of stackless coroutines that need async/await and colored functions. This creates all the friction the article laments over. But it also praises Go for its implementation, which is also based on a coroutine of a different kind. Stackful coroutines, which do not have any of these problems. Rust considered using those (and, at…

> because stackfull coroutine requires a runtime that preempts coroutines I've used stackful coroutines many times in many codebases. It never required or used a runtime or preemption. I'm not sure why having a runtime that preempts them would even be useful, since it defeats the reason most people use stackful coroutines in the first place.

"stackful coroutines" the control-flow primitive is cumbersome to build on top of "green threads" but for use cases that are mostly about blocking on lots of distinct I/O calls at the same time people may be indifferent between these two things. These conversations are often muddled because the feature shipped most often is called "async" and not called "jump to another stack please" :(

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

#190

Earlier quoted context omitted.

> But then rust also has channels. When you read about it, it talks about "messages", which to me means little objects. Like a few bytes little. This is the solution, pretty much everything I write now is just a few tasks that service some channels. They look at what's arrived and if there's something to output, they will put a message on the appropriate channel for another task to deal with. No sharing objects or an…

Why does Smalltalk constantly get credit for being true OOP? Simula was doing OOP long before Smalltalk. Most languages choose Simula style OOP, and reject the things that make Smalltalk different. If you say Smalltalk is better OOP I might agree, but calling it "true" is not correct.

Because the term was coined by Alan Kay, who apparently later said he probably should have called it message oriented (paraphrasing).

There's also a written conversation you can find online where he disqualifies pretty much all of the mainstream languages of being OO.

A lot of people, like you, say that OO == ADTs. Or rather, what ever Simula, C++ and Java are doing. Some will say that inheritance is an integral part of it, other's say it's all about interfaces.

But then there's people who say that Scheme and JavaScript are more object oriented than Java and C#. Or that when we're using channels or actors we're now _really_ doing OOP.

There's people who talk about patterns, SOLID, clean code and all sorts of things that you should be adhering to when structuring OO code.

Then there's people who say that OO is all about the mental model of the user and their ability to understand your program in terms of operational semantics. They should be able to understand it to a degree that they can manipulate and extend it themselves.

It's all very confusing.

Post reply on HN