Earlier quoted context omitted.
Are you talking about threads-the-programming-model (vs. events, callbacks, channels, futures/promises, dependency graphs), or are you talking about threads-the-implementation-technique (vs. processes or various select()-like mechanisms)? And if you are talking about threads-the-programming-model, which synchronization mechanism: locks, monitors, channels/queues, transactional memory? If the various threads in your a…
Do you have any links on the "dependency-graph dataflow system" that you are talking about? Sounds a little bit similar to what I'm trying to do, except at higher scale.
Asynchronous IO in Rust
21–30 of 111 posts
Re: Asynchronous IO in Rust
#22Earlier quoted context omitted.
Are you talking about threads-the-programming-model (vs. events, callbacks, channels, futures/promises, dependency graphs), or are you talking about threads-the-implementation-technique (vs. processes or various select()-like mechanisms)? And if you are talking about threads-the-programming-model, which synchronization mechanism: locks, monitors, channels/queues, transactional memory? If the various threads in your a…
Do you have any links on the "dependency-graph dataflow system" that you are talking about? Sounds a little bit similar to what I'm trying to do, except at higher scale.
https://github.com/google/guice
https://github.com/square/dagger
Imagine injecting Futures into your code. Now imagine injecting them, but having the Provider record a lot of metadata about who you were calling, how you were calling it, how long it took, whether an error occurred, letting an SRE turn off the call, etc.
Re: Asynchronous IO in Rust
#23Earlier quoted context omitted.
Well, I believe that it's almost impossible to make rust threads lightweight because every green thread needs a stack anyway. This may be fixed with some stuff like `async/await`. But let's talk about what's wrong with threads: 1. Timeout handling is ugly: you need to account a timeout in each read and write operation. At least timeout handling makes coroutine/threaded code no better than state machine code. But actu…
I've been writing in this model for nearly ten years now. In practice, what you cite as problems aren't. 1: In either approach, somewhere in your event loop you're setting yourself a timeout to fire. Haskell & Erlang do use exceptions, but Go does not, it simply makes this a first-class concern of the core event loop. This is only a problem in languages where the threading was bolted on after-the-fact. Which is a lot…
Thread 1 sends message A to thread 2 and waits for a response.
As part of processing message A, thread 2 sends message B to thread 1 and waits for a response... forever, since thread 1 is blocked waiting for thread 2...
Re: Asynchronous IO in Rust
#24Earlier quoted context omitted.
There are some examples of speed difference at https://en.m.wikipedia.org/wiki/Green_threads Basically if you have green threads with only one core, you don't need to do as much work with locking.
The argument here is less about the performance difference existing or not, and that the decision in question sounds to have been made due to the lack of something we care less about.
Re: Asynchronous IO in Rust
#25Earlier quoted context omitted.
I've been writing in this model for nearly ten years now. In practice, what you cite as problems aren't. 1: In either approach, somewhere in your event loop you're setting yourself a timeout to fire. Haskell & Erlang do use exceptions, but Go does not, it simply makes this a first-class concern of the core event loop. This is only a problem in languages where the threading was bolted on after-the-fact. Which is a lot…
"Communicating" doesn't solve deadlocks. Thread 1 sends message A to thread 2 and waits for a response. As part of processing message A, thread 2 sends message B to thread 1 and waits for a response... forever, since thread 1 is blocked waiting for thread 2...
And to be fair, it does significantly reduce the risk of deadlock by avoiding the complexity of explicit mutexes and condition variables.
Re: Asynchronous IO in Rust
#26Earlier quoted context omitted.
> Green threads didn't provide performance benefits over native threads in Rust. That's why they were removed. This seems wrong. This shouldn't be the point of green threads -- green threads aren't a "faster" alternative to native threads. How would that work? How could it be the case that virtual threads implemented in user space are faster than native threads provided by the OS? I don't think anyone expects that to…
There are some examples of speed difference at https://en.m.wikipedia.org/wiki/Green_threads Basically if you have green threads with only one core, you don't need to do as much work with locking.
This is half the basis for the original design of the Erlang BEAM VM. SMP was a grudging afterthought; the original concept was that each VM "node" was a single scheduler process bound to a single core, and then you tied those nodes together into a (machine-internal) multi-core distributed system, effectively creating a set of "threads" communicating over socket-based message-passing IPC, rather than shared memory.
M:N scheduling—where, critically, a task can be re-scheduled from one core to another—is a much more complex and less-predictable design, that's not always worth the trouble. For Erlang's particular use-cases, it turned out to be worth the trouble enough to justify programming it, eventually. But the SMP VM is still only built via a configure flag, rather than displacing the M:1 VM as "the" VM.
Re: Asynchronous IO in Rust
#27Earlier quoted context omitted.
> Green threads didn't provide performance benefits over native threads in Rust. That's why they were removed. This seems wrong. This shouldn't be the point of green threads -- green threads aren't a "faster" alternative to native threads. How would that work? How could it be the case that virtual threads implemented in user space are faster than native threads provided by the OS? I don't think anyone expects that to…
Rust's green threading was... unusual. It attempted to abstract green and native threads into a single API, which lead to a lot of unnecessary overhead: https://github.com/rust-lang/rfcs/blob/0806be4f282144cfcd55b... Sadly, that proposal also removed concurrent IO from the standard library, and it hasn't been replaced.
Re: Asynchronous IO in Rust
#28Earlier quoted context omitted.
"Communicating" doesn't solve deadlocks. Thread 1 sends message A to thread 2 and waits for a response. As part of processing message A, thread 2 sends message B to thread 1 and waits for a response... forever, since thread 1 is blocked waiting for thread 2...
I don't understand that scenario — isn't message B the message thread 1 is waiting for? And to be fair, it does significantly reduce the risk of deadlock by avoiding the complexity of explicit mutexes and condition variables.
Certainly a bit more contrived then deadlock with locks, though (which you can easily do with even a single thread, even in Rust).
Re: Asynchronous IO in Rust
#29If you use threads, green or otherwise, you don't have to "implement" special code for composing things together, you get the full set of tools for composing code together, which includes, in passing, state machines, among all the other things it includes. This basically implements an Inner Platform Effect of an internal data-based language for concurrency that the language interprets, which will A: forever be weaker…
Re: Asynchronous IO in Rust
#30Earlier quoted context omitted.
> What's so wrong with Rust threads, excepting perhaps them being heavyweight? (Far better to solve that problem directly.) Nothing. If threads work fine, use them! That's what most Rust network apps do, and they work fine and run fast. A modern Linux kernel is very good at making 1:1 threading fast these days. > And having written network servers with pretty much every abstraction so much as mentioned in the article…
I'm down with all that. I'm really arguing in favor of threading here rather than any particular model of it. Plus, if you write threaded code, you can change the runtime out. Rust guarantees all the hard parts, anyhow. I wouldn't even be surprised once Rust settles down further it turns out there's some sort of hybrid solution that is better than either 1:1 or M:N on its own because it has superior insight into what…
Oh, from an ergonomic point of view I'm in total agreement that imperative-looking code is the best. I've never liked explicit node.js-like continuation passing style or what have you.