Live data from Hacker News

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

bitbashing.io

561–570 of 624 posts

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

#561

Earlier quoted context omitted.

I disagree with you in the last point, async is definitely painful for end users. It indeed feels like you're using a completely different language, which has Rust's core features removed – lifetimes and explicit types, sprinkled with a mess of Pins on top. You cannot run scoped fibers, forcing you to "Arc shit up", Pins are unusable without unsafe, and a tiniest change in an async-function could make the future !Sen…

It may no longer be necessary for pins to exist for async implementation: https://doc.rust-lang.org/std/rc/struct.Rc.html#method.new_c... (but the current async interface requires using them, so my point is definitely a whatifism).

Replacing Pin with Rc is what they refer to as "Arc shit up". Pin avoids the need for a heap allocation like Rc/Arc entirely.

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

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

> The main problem is that tokio futures are 'static

An important distinction to make is that tokio Futures aren't 'static, you can instead only spawn (take advantage of the runtime's concurrency) 'static Futures.

> This implies that you can't statically guarantee that a future is cleaned up properly.

Futures need to be Pin'd to be poll()'d. Any `T: !Unpin` that's pinned must eventually call Drop on it [0]. A type is `!Unpin` if it transitively contains a `PhantomPinned`. Futures generated by the compiler's `async` feature are such, and you can stick this in your own manually defined Futures. This lets you assume `mem::forget` shenanigans are UB once poll()'d and is what allows for intrusive/self-referential Future libraries [1]. The future can still be leaked from being kept alive by an Arc/Rc, but as a library developer I don't think you can/would-care-to reasonably distinguish that from normal use.

[0]: https://doc.rust-lang.org/std/pin/#drop-guarantee

[1]: https://docs.rs/futures-intrusive/latest/futures_intrusive/

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

#563

Earlier quoted context omitted.

You can call .Wait on the Task it returns :)

Right, but now you are forced to convert the calling function to async. u32 / float does not have the problem. It does not "bubble up", unless you want it to.

no, .Wait in C# or block_on in Rust keep the caller sync while evaluating the async callee, preventing the "bubble up".

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

#564
post #323

Earlier quoted context omitted.

> I want to know if the function I'm calling is going to make a network request. That has nothing to do with function coloring. > Ideally I want to have the fundamental behavior of any function I call encoded in the function signature. There is no distinction of async functions if you don't have function coloring that you can encode in type signatures.

> That has nothing to do with function coloring. Sure, in the same way that types have nothing to do with enforcing logical correctness of software. > There is no distinction of async functions if you don't have function coloring that you can encode in type signatures. What are you trying to say with this statement?

getaddrinfo() is a synchronous function that can do network requests to resolve DNS. The network property isn't reflected in its function signature becoming async. You can have an async_getaddrinfo() which does, but the former is just a practical example of network calls in particular being unrelated to function coloring.

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

#565

Earlier quoted context omitted.

No? You don't need parallelism to guarantee global progress as long as the scheduler has the ability to preempt tasks. Of course coroutines (as opposed to e.g. userspace threads) can't really be preempted, which is the issue here.

> parallelism to guarantee global progress as long as the scheduler has the ability to preempt task Preempting tasks is a single-core simulation of parallelism. I suspect there is confusion about what parallelism and concurrency are here: the terms are often used interchangeably (especially saying "concurrency" instead of "parallelism"), but they are definitely not interchangeable - or even, arguably, related at all.…

Preemption simulates localized concurrency (running multiple distinct things logically at the same time) not parallelism (running them physically at the same time). You can have concurrency outside continuations. OS threads for example are not continuations, but still express concurrency to the kernel so that it can (not guaranteed) express concurrency to the physical CPU cores which hopefully execute the concurrent code in parallel (not guaranteed again, due to hyperthreading).

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

#566
post #292

Earlier quoted context omitted.

There's a good chance this is rather a Go issue than a GC one. People get fooled by Go's pretense to be a high level C replacement. It is highly inadequate at performing this role at best. The reason for that is the compiler quality, the design tradeoffs and Go's GC implementation throughput are simply not there for it to ever be a good general purpose systems-programming-oriented language. Go receives undeserved hyp…

As an ops guy for decades, it makes me laugh to hear claims about Java GC superiority. Please go back in time and fix all the crashes and OOMs caused by enterprise JVM, as opposed to near-zero problems with the Go deployments. Making stong statements without a backup in hard facts is a sign of zealotry...

it makes me laugh to hear claims about Java GC superiority. Please go back in time and fix all the crashes and OOMs caused by enterprise JVM,

I don’t see how running into an OOM problem is necessarily a problem with the GC. That said, Java is a memory intensive language, it’s a trade off that Java is pretty up front about.

I don’t have a horse in this race but I would be quite surprised if Go’s GC implementation could even hold a candle to the ones found in C# and Java. They have spent literally decades of research and development, and god knows how much money (likely north of $1b), optimizing and refining their GC implementations. Go just simply lacks any of the sort of maturity and investment those languages have.

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

#567
post #549
post #240

Earlier quoted context omitted.

I'm doing basically the same thing in Java for an MMO and the JDK makes it so easy. Just move objects via concurrent queues from network to model creation to UI threads. It's actually quite boring, and fast!

Non-blocking I/O is quite mature on Java, and it shows. Unfortunately Java is still a rabid devourer of memory. Its RAM consumption tends to be the biggest con whenever evaluating the pros of using Java. Sometimes it's worth it. More and more often it's not anymore.

I think the game takes a few hundred mb to run while zooming out of a city right now.

FastComments pubsub system in Java takes less than 500mb of heap for like 100k subscribers.

But yes, you have to worry about object field count.

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

#568

Earlier quoted context omitted.

> How is this the most loved language? Personal preference and pain tolerance. Just like learning Emacs[1] - there's lots of things that programmers can prioritize, ignore, enjoy, or barely tolerate. Some people are alright with the fact that they're prototyping their code 10x more slowly than in another language because they enjoy performance optimization and seeing their code run fast, and there's nothing wrong wit…

> even if it's still very un-productive next to productivity-oriented languages (e.g. Python). The thing is, for many people, including me, Rust is actually a more productive language than Python or other dynamic languages. Actually writing Python was an endless source of pain for me - this was the only language where my code did not initially work as expected more times than it did. Where in Rust it works fine from…

> Python or other dynamic languages

I should have stated that I'm comparing Rust to typed Python (or TypeScript or typed Racket or whatever). Typed Python gives you a type system that's about a good as Rust's, and the same kinds of autocompletion and inline documentation that you would get with Rust, while also freeing you from the constraints of (1) being forced to type every variable in your program upfront, (2) being forced to manage memory, and (3) no interactive shell/REPL/Jupyter notebooks - Rust simply can't compete against that.

You're experience would likely have been very different if you were using typed Python.

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

#569

Earlier quoted context omitted.

> could be async IO and require being called in the context of an async runtime The compiler already has knowledge that a function is being called as async - what prevents it from ensuring that a runtime is present when it does? > blocking synchronously on an async task in an async runtime can result in deadlocks from task waiting on runtime IO polling but the waiting preventing the runtime from being polled What pre…

> what prevents it from ensuring that a runtime is present when it does? The runtime being a library instead of a language/compiler level feature. Custom runtimes is necessary for systems languages as they can have specialized constraints. EDIT: Note that it's the presence of a supported runtime for the async operation (e.g. it relies on runtime-specific state like non-blocking IO, timers, priorities, etc.), not only…

Thank you for your explanation of the trade-space around preemptible coroutines, that greatly helped my understanding. I am still unclear on one thing:

> The runtime being a library instead of a language/compiler level feature. Custom runtimes is necessary for systems languages as they can have specialized constraints.

Compilers link against dynamic libraries all the time. What prevents the compiler from linking against a hypothetical libasync.so just like any other library? (alternatively, if you want to decouple your program from a particular async runtime, what prevents the language from defining a generic interface that async runtimes must implement, and then linking against that?)

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

#570

Earlier quoted context omitted.

So you use a safe, garbage-collected language like Python, and iterate 5x as fast as Rust. Problem solved. It's 2023 - there are at least a dozen production-quality safe languages.

> and iterate 5x as fast as Rust. I've been involved in Java, Python, PHP, Scala, C++, Rust, JS projects in my career. I think I'd notice a 5x speed difference in favor of Python if it existed. But I haven't.

You're probably just using Python wrong, then. You can use a Jupyter notebook to incrementally develop and run pieces of code in seconds, and this scales to larger programs. With Rust, you have to re-compile and re-run your entire application every time you want to test your changes. That's a 5x productivity benefit by itself.
Post reply on HN