Earlier quoted context omitted.
Right, that specific instance is essentially a single-threaded* application. Now imagine that you spawned a few hundred of them with JoinAll. Each would run, multiplexed within a single thread, with execution being passed at the await points. * anyone know the correct nomenclature for this? Single-coroutine?
Cooperative threads are still threads, they just aren't preemptive.
Async-std: an async port of the Rust standard library
121–130 of 238 posts
Re: Async-std: an async port of the Rust standard library
#122Earlier quoted context omitted.
> I thought Rust had other, better ways to create non-blocking code so I don't understand why to use async instead. In fact, Rust does have a great solution for nonblocking code: just use threads! Threads work great, they are very fast on Linux, and solutions such as goroutines are just implementations of threads in userland anyway. (The "what color is your function?" post fails to acknowledge that goroutines are jus…
Threads are bad for high concurrency. Specifically when you need to call out to another service that has some latency. Say you have 1000 threads. To handle a request each one needs to make 50ms of external or DB calls. In one second, each thread can handle 20 calls. So you can handle 20k requests/second with 1000 threads. But Rust is so fast it can serve 500k requests a second. So with regular threads, you need ~25,0…
Re: Async-std: an async port of the Rust standard library
#123Earlier quoted context omitted.
They are very similar. In cooperative multitasking, programs yield the thread to the OS, while async programs yield to the event loop. In both cases, yielding is voluntary. Are there other differences? It's probably quite easy to turn a program written one way into the other. Edit: I just remembered that in cooperative multitasking, it's probably possible for the OS to safely save the program stack pointer, meaning t…
Even conceptually the models are very different, in one control is just given up and regained unpredictably, while in the other one it is programmed, hence asynchronous programming, not multitasking.
Which one? It’s “cooperative” ie not unpredictable. The points where one can block are predictable and documented explicitly, otherwise how would the programmer know they won’t block forever. The same should hopefully be the case for async/awaitable apis.
In fact where async/await will actually give up control are harder to tease out.
The differences are really not as big as they would seem.
Re: Async-std: an async port of the Rust standard library
#124Earlier quoted context omitted.
> I thought Rust had other, better ways to create non-blocking code so I don't understand why to use async instead. In fact, Rust does have a great solution for nonblocking code: just use threads! Threads work great, they are very fast on Linux, and solutions such as goroutines are just implementations of threads in userland anyway. (The "what color is your function?" post fails to acknowledge that goroutines are jus…
Threads are bad for high concurrency. Specifically when you need to call out to another service that has some latency. Say you have 1000 threads. To handle a request each one needs to make 50ms of external or DB calls. In one second, each thread can handle 20 calls. So you can handle 20k requests/second with 1000 threads. But Rust is so fast it can serve 500k requests a second. So with regular threads, you need ~25,0…
With 8k stack for each, you can easy have 10k-100k threads in a low-end system
Re: Async-std: an async port of the Rust standard library
#125Earlier quoted context omitted.
> You write sync code, but because Go routines aren’t OS threads they operate with the efficency of async code. No, they don't. Goroutines have stacks, while Rust async code does not. Go has to start stacks small and copy and grow them dynamically because it doesn't statically know how deep your call stack is going to get, while async/await compiles to a state machine, which allows for up-front allocation. Furthermor…
> OS threads are not significantly different from goroutines in terms of efficiency This is not true for a use case with a lot of connections, additionally context switch cost a lot more now with all side channel attack mitigations on.
Re: Async-std: an async port of the Rust standard library
#126Earlier quoted context omitted.
> Its literally taken five years to get back to an alpha thats not as good The new I/O system is better in several ways. First, as you acknowledged, not everyone writes servers that need high scalability. M:N has no benefit for those users, and it severely complicates FFI. Second, async is faster than M:N because it compiles to a state machine: you don't have a bunch of big stacks around.
Yes, its better in several ways, but its also worse in several ways. It will take another five years to build a robust ecosystem for servers, and you'll still have to be careful not to import the wrong library or std module and accidentally block your scheduler. Plus the extra noise of .await? everywhere. I'm not saying it was the wrong decision five years ago, but it definitely was a choice and there could have been…
Re: Async-std: an async port of the Rust standard library
#127Earlier quoted context omitted.
The key difference is cooperative multitasking lets the program yield the thread anywhere, not just to the event loop like async programming. Arbitrary yielding was a feature that programmers widely abused in the early Windows days. The user would start something in an app that takes some time to complete; the app would freeze for a while, but all other apps remained usable. It was obvious that the programmers, rathe…
>It's a good thing that async programming frameworks don't usually allow yielding from arbitrary places. Well.. await new Promise((res, rej) => { setImmediate(res); }) (In environments without `setImmediate` this is easily shimmed - https://github.com/YuzuJS/setImmediate )
Re: Async-std: an async port of the Rust standard library
#128Earlier quoted context omitted.
> I thought Rust had other, better ways to create non-blocking code so I don't understand why to use async instead. In fact, Rust does have a great solution for nonblocking code: just use threads! Threads work great, they are very fast on Linux, and solutions such as goroutines are just implementations of threads in userland anyway. (The "what color is your function?" post fails to acknowledge that goroutines are jus…
Threads are bad for high concurrency. Specifically when you need to call out to another service that has some latency. Say you have 1000 threads. To handle a request each one needs to make 50ms of external or DB calls. In one second, each thread can handle 20 calls. So you can handle 20k requests/second with 1000 threads. But Rust is so fast it can serve 500k requests a second. So with regular threads, you need ~25,0…
Re: Async-std: an async port of the Rust standard library
#129I must be dumb, because every time I dive into async/await, I feel like I reach an epiphany about how it works, and how to use it. Then a week later I read about it again and totally lost all understanding. What do I gain if I have code like this [0], which has a bunch of `.await?` in sequence? I know .await != join_thread(), but doesn't execution of the current scope of code halt while it waits for the future we are…
async/await are coroutines and continuations (bear with me). Here is synchronous code: result = server.getStuff() print(result) Here is synchronous code, that tries to be asynchronous: server.getStuff(lambda result: print(result)) Once server.getStuff returns, the callback passed to it is called with the result. Here is the same code with async/await: result = await server.getStuff() print(result) Internally, the com…
Re: Async-std: an async port of the Rust standard library
#130Earlier quoted context omitted.
> async-std has the equivalent of std::net::TcpListener, however it does not appear to actually impl AsyncRead / AsyncWrite. So as of now you can't do anything with it. TcpStream does impl them, at least. It does implement AsyncRead and Write, because anything with `Read` and `Write` implements it: https://docs.rs/async-std/0.99.3/async_std/io/trait.Read.htm... (that's sadly a little backwards by rustdoc) The problem…
>It does implement AsyncRead and Write, because anything with `Read` and `Write` implements it: https://docs.rs/async-std/0.99.3/async_std/io/trait.Read.htm... (that's sadly a little backwards by rustdoc) >impl Read for T { That's saying that anything that impls futures::AsyncRead impls async_std::io::Read. async_std::net::TcpListener does not impl AsyncRead. (Compare with TcpStream and File which do.) >Hyper can bes…