Live data from Hacker News

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

bitbashing.io

311–320 of 624 posts

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

#311
post #92

Earlier quoted context omitted.

It really is, but I still favour "unsexy" manual poll/select code with a lot of if/elseing if it means not having to deal with async. I fully acknowledge that I'm an "old school" system dev who's coming from the C world and not the JS world, so I probably have a certain bias because of that, but I genuinely can't understand how anybody could look at the mess that's Rust's async and think that it was a good design for…

> It really is, but I still favour "unsexy" manual poll/select code with a lot of if/elseing if it means not having to deal with async. > I fully acknowledge that I'm an "old school" system dev who's coming from the C world and not the JS world, so I probably have a certain bias because of that, but I genuinely can't understand how anybody could look at the mess that's Rust's async and think that it was a good design…

Isn't mixing async and sync code like this a recipe for deadlocks?

What if your example code is holding onto a thread that foo() is waiting to use?

Said another way, explain how you solved the problems of just synchronously waiting for async. If that just worked then we wouldn't need to proliferate the async/await through the stack.

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

#312
post #100

I've been writing a lot of async lock free rust. The main problem is that tokio futures are 'static, which is because of a design mistake that's baked deep into the rust ecosystem: Leaking memory is 'safe'. This implies that you can't statically guarantee that a future is cleaned up properly, which means that if you spawn some async work, something may std::mem::forget a future, and then the borrow checker won't know…

> which is because of a design mistake that's baked deep into the rust ecosystem: Leaking memory is 'safe'. Would you prefer not to have internal mutability, not to have `Rc`, or have them but with infectious unsafe trait bounds, or something else?

I don’t see why it would be an either/or. For instance, Rc does not leak memory, and neither do many cases of interior mutability.

If an API leaks memory, then I’d like it to be deemed unsafe. That way, leaking a future would be unsafe, so the borrow checker could infer (transitively) that freeing the future means that any references it had are now dead (as it can already infer when a synchronous function call pops returns).

Am I missing something subtle?

Edit: Rc with cycles would be a problem. I rarely intentionally use Rc though (certainly less often than I create a future).

Edit 2: maybe an auto trait could statically disallow Rc cycles somehow?

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

#313
post #280

OK, I suppose I should write to this. As I've mentioned before, I'm writing a high performance metaverse client. Here's a demo video.[1] It's about 40,000 lines of Rust so far. If you are doing a non-crappy metaverse, which is rare, you need to wrangle a rather excessive amount of data in near real time. In games, there's heavy optimization during game development to prevent overloading the play engine. In a metavers…

> Yes, sometimes you can get stuck for a day, trying to express something within the ownership rules. This is a big problem. Fast iteration time is very valuable. And who likes doing this to themselves anyway? Isn't it a very frustrating experience? How is this the most loved language?

Debugging rare crashes and heisenbugs is more frustrating, and in non-safe languages, a chronic problem.

Whereas after you prove the safety of a design once, it stays with you.

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

#314

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…

The reason Rust chose stackless coroutines is because it allows zero cost FFI, which for a systems language is extremely important.

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

#315

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…

> This is the same technique used in Go and many others for preemption. If you don't add this, futures that don't yield can run forever, stalling the system.

You may be referring to this particular issue in Go https://github.com/golang/go/issues/10958 which I think was somewhat addresses a couple releases back.

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

#316

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

Yes, I think you're generally right. I'm a big fan of this blog post: https://eli.thegreenplace.net/2018/measuring-context-switchi... > The numbers reported here paint an interesting picture on the state of Linux multi-threaded performance in 2018. I would say that the limits still exist - running a million threads is probably not going to make sense; however, the limits have definitely shifted since the past, and a…

so, in that benchmark, context switch is comparable to copying 64k mem, which is kinda significant, I run some heavy load database with few hundreds threads, and see that it does 100k context switching per sec some times.

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

#317

Earlier quoted context omitted.

Yes. That atomized model of concurrency where your state goes everywhere and you somehow collect it back at some point was always (literally) the textbook example of how not to do it. It was created to be an improvement over the Javascript situation, and somehow every language that had a sane structure adopted it as if it was not only good, but the way to do things. This is insane.

> It was created to be an improvement over the Javascript situation I see this repeated everywhere in this thread. async/await originated in C# not JS.

The C# implementation is clearly an attempt of putting type-safety over exactly the same implementation JS promises use. Done because MS wanted to port the same behavior.

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

#318
post #36

Earlier quoted context omitted.

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.

We need a way to bridge the gap. Having a runtime may not be suitable for all apps but it can easily allow you to reach 95%+ concurrency performance. The async compile-to-state-machine model is only necessary for the last 5%. Most userland apps rarely need to maximize concurrency efficiency. They need concurrency yes, but performance at the 95th percentile is more than sufficient.

I really don’t buy this argument that only some small “special” fraction of apps “actually” need async, and for the rest of us “plebs” we should be relegated to blocking.

Async is just hard. That’s it. It’s fundamentally difficult.

In my experience language implementations of async fall into 2-axes: clarity and control. C# is straightforward-enough (having cribbed its async design off functional languages) but I find it scores low on the “clarity” scale and moderate-high in control, because you could control it, but it was t always clear.

JS is moderate-high clarity, low control: easy to understand, because all the knobs are set for you. Before it got async/await sugar, I’d have said it would have been low clarity, because I’ve seen the promise/callback hell people wrote when given rope.

Python is the bottom of the barrel for both clarity and control. It genuinely has to have the most awful and confusing async design I’ve ever seen.

I personally find Rust scores high in both clarity and control. Playing with the Glommio executor was what really solidified my understanding of how async works however.

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

#319

Earlier quoted context omitted.

Cheering for your metaverse app. Hope to hear more about it. I suspected you might be doing gamedev but this is the first time you’ve shown extensive work. One challenge with rust is that (for better or worse) most gamedev talent is C++. If you ever open source it I’d be interested in contributing, though I’m not sure how effective the contributions would be. Good luck!

Email sent. I'm not that interested in self-promotion here as I am in getting more activity on Rust graphics development. I think the Rust core graphics ecosystem needs about five good graphics people for a year to get unstuck. Rust is a good language for this sort of thing, but you've got to have reliable heavy machinery down in the graphics engine room. Until that exists, nobody can bet a project with a schedule an…

Is it the one by the same guy who made the gold-standard moddable racing simulator?

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

#320
post #141

Earlier quoted context omitted.

That was the argument for Go. But Go is not used that way. People still share and lock stuff in Go. Go is only safe for race conditions that break the memory model, not all race conditions, as Rust is.

Rust protects against data races, not race conditions. https://doc.rust-lang.org/nomicon/races.html

Go doesn’t protect against even those, which is what the parent meant
Post reply on HN