Earlier quoted context omitted.
The safety argument is actually the reason why you can use Rust in those cases to begin with. If it was C or C++ you simply couldn't use it for things like webservers due to the safety problems inherent to these languages. So Rust creeps into the part of the market that used to be exclusive to GC languages.
What do you think nginx and Apache are written in?
Maybe Rust isn’t a good tool for massively concurrent, userspace software
551–560 of 624 posts
Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software
#552Earlier quoted context omitted.
Async as a paradigm seems so against what GP was discussing. If I understood, and from my experience, we're talking more about concurrent execution with carefully-designed priorities, locks, and timing requirements. This is closer to the embedded / systems-level concurrency, if I understand it right. Are we really expecting a coroutine/ async style to just lift into this world?
Threads are for doing your own work in parallel. Async is for waiting on others to do their work in parallel. Your own work would be some CPU-intensive operations you can logically divide and conquer. Others' work would be waiting for file I/O from the OS, waiting for a DB result set following a query, waiting for a gRPC response, etc. Conceptually quite distinct, and there are demonstrated advantages and drawbacks t…
Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software
#553Earlier quoted context omitted.
Yes actually it is solved. If you stick to async then it cannot deadlock (in this way) because you yield execution to await.
> Yes actually it is solved. If you stick to async then it cannot deadlock (in this way) because you yield execution to await. Maybe I'm misunderstanding what you are saying. I use the word "_implementation_type_" below to mean "either implemented as option 1 or option 2 from my post above." With current asynchronous implementations (like JS, Rust, etc), any time you use `await` or similar, that statement may never r…
A is sychrounously waiting B which is awaiting C which could complete but never gets scheduled because A is holding onto the only thread. Its a very common situation when you mix sync and async and you're working in a single threaded context, like UI programming with async. Of course it can also cause starvation and deadlock in a multithreaded context as well but the single thread makes the pitfall obvious.
Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software
#554Earlier quoted context omitted.
You need to `block_on` only if you need to block on async code. But you don't need to block on order to run async code. You can spawn async code without blocking just fine and there is no risk of deadlocks.
Now you lose determinism in tear down though.
And this would be basically what you have to do in Go anyways - you need to explicitly use defer if you want code to run on destruction, with the caveat that in Go nothing stops you from forgetting to call it, when in Rust I can at least have a deterministic guard that would panic if I forget to call the explicit destructor before the object getting out of scope.
BTW async drop is being worked on in Rust, so in the future this minor annoyance will be gone
Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software
#555Earlier quoted context omitted.
UI in Rust without inheritance is tricky. There's still no great UI framework written in Rust yet, though not for lack of trying! I'm interested to see how Bevy's UI turns out. They're currently exploring the design space and requirements for production-grade UI, actually.
Wouldn’t something akin to swift UI work well in this situation? I can understand that not having a “component” class to inherit would make building custom components difficult, but if most layout and skinning can be accomplish via functions then you can sidestep the issue for most cases I think…
Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software
#556Earlier quoted context omitted.
Now you lose determinism in tear down though.
Ok, in a very, very rare case (so far never happened to me) when I really need to await an async operation in the destructor, I just define an additional async destructor, call it explicitly and await it. Maybe it's not very elegant but gets the job done and is quite readable as well. And this would be basically what you have to do in Go anyways - you need to explicitly use defer if you want code to run on destructio…
Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software
#557Earlier quoted context omitted.
To run async in Drop in rust, you need to use block_on() as you can't natively await (unlike in Go). This is the "blocking on Drop" mentioned and can result in deadlocks if the async logic is waiting on the runtime to advance, but the block_on() is preventing the runtime thread from advancing. Something like `async fn drop(&mut self)` is one way to avoid this if Rust supported it.
You need to `block_on` only if you need to block on async code. But you don't need to block on order to run async code. You can spawn async code without blocking just fine and there is no risk of deadlocks.
Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software
#558Earlier quoted context omitted.
It doesn't really matter, there doesn't exist a problem space where both Rust and Python are reasonable choices. Case in point, I once wrote a program to take a 360 degree image and rotate it so that the horizon followed the horizontal line along the middle, and it faced north. I wrote it in python first and running it on a 2k image took on the order of 5 minutes. I rewrote it in rust and it took on the order of 200m…
> there doesn't exist a problem space where both Rust and Python are reasonable choices This thread, and many other threads about Rust, are filled with people arguing the exact opposite - that Rust is a good, productive language for high-level application development. I agree with you, there's relatively little overlap - that's what I'm arguing for!
Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software
#559Earlier quoted context omitted.
The performance overhead of threads is largely unrelated to how many you have. The thing being minimized with async code is the rate at which you switch between them, because those context switches are expensive. On modern systems there are many common cases where the CPU time required to do the work between a pair of potentially blocking calls is much less than the CPU time required to yield when a blocking call occ…
The cost of context switching in "async" code is very rarely smaller than the cost of switching OS threads. (Exception is when you'ree using a GC language with some sort of global lock.) "Async" in native code is cargo cult, unless you're trying to run on bare metal without OS support.
Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software
#560Earlier 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…
https://tokio.rs/blog/2020-04-preemption#a-note-on-blocking
> Tokio does not, and will not attempt to detect blocking tasks and automatically compensate