Live data from Hacker News

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

bitbashing.io

211–220 of 624 posts

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

#211
post #196

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…

The author does mention that you should probably stop at using Threads and passing data around via channels... but then mentions the C10K problem and says that sometimes you need more... but does not answer the question that I think is begging to be asked: does using Rust async with all the complications (Arc, cloning, Mutex whatever) does actually outperform Threads/channels?? Even if it does, by how much? It would…

If your system cannot be decomposed away from shared mutable state, then you cannot avoid lifetime management and synchronization primitives.

Ultimately, it depends on your data model.

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

#212
post #3

I love Rust, but async is a hot mess and you cannot just write async code the same way that you write sync code. I'm getting more convinced that mixing the two is a bad idea, and that Go's approach of making everything sync with a single async channel primitive might be right. I'm currently plumbing through some logic to call a sync method on a struct that implements Future and it's... an interesting challenge. While…

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

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

#213

Earlier quoted context omitted.

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 th…

No, tokio does not require your Futures to be thread-safe.

Every executor (including tokio) provides a `spawn_local` function that spawns Futures on the current thread, so they don't need to be Send:

https://docs.rs/tokio/1.32.0/tokio/task/fn.spawn_local.html

I have used Rust async extensively, and it works great. I consider Rust's Future system to be superior to JS Promises.

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

#214

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 remember picking up this sort of advice from a professor way back in college. It's a godsend. Structure the problem as data flowing between tasks and connect them up with queues, avoid sharing state. It's just a better way to deal with multithreading no matter what language you use.

I like this too.

I would also suggest looking into ringbuffers and LMAX Disruptor pattern.

There is also Red Planet Lab's Rama, which takes the data flow idea and uses it to scale.

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

#215
post #151

Rust made a critical safety mistake when it chose its async paradigm. It gave the code the option to decide when to yield. What that means is that when I'm writing async code, I have to audit every library I import to make sure that library is guaranteed to yield after a few microseconds of execution, otherwise my own core loops starve. Importing unknown code when using async rust is not safe for any application that…

> A safe async language must guarantee that threads will make progress.

You might be looking for parallelism, not concurrency.

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

#216
post #193

Earlier quoted context omitted.

> 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 th…

So with another async runtime it's possible to write async Rust that doesn't need to be thread-safe??? Can you show some example?

You don't even need other runtimes for this. Tokio includes a single-threaded runtime and tools for dealing with tasks that aren't thread safe, like LocalSet and spawn_local, that don't require the future to be Send.

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

#217
post #193

Earlier quoted context omitted.

> 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 th…

So with another async runtime it's possible to write async Rust that doesn't need to be thread-safe??? Can you show some example?

Every executor (including tokio) supports spawning Futures that aren't Send:

https://docs.rs/tokio/1.32.0/tokio/task/fn.spawn_local.html

There is a lot of misinformation in this thread, with people not knowing what they're talking about.

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

#218
post #183
post #168

Earlier quoted context omitted.

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.

Ah, my mistake.

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

#219
Async Rust also ends up with these super nasty types involving Future that can't even be named half the time and you have to refer to them by existential types, like `impl Future`.

But these existential types can only be specified in function return or parameter position, so if you want to name a type for e.g.:

  let x = async { };
You can't! Because you can only refer to it as `impl Future` but that's not allowed in a variable binding!

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

#220

Earlier quoted context omitted.

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 th…

>but Tokio forces all of your async functions to be multi thread safe

While there are other runtimes that are always single-threaded, you can do it with tokio too. You can use a single threaded tokio runtimes and !Send tasks with LocalSet and spawn_local. There are a few rough edges, and the runtime internally uses atomics where a from-the-ground-up single threaded runtime wouldn't need them, but it works perfectly fine and I use single threaded tokio event loops in my programs because the tokio ecosystem is broader.

Post reply on HN