Earlier quoted context omitted.
> Considering a normal-sized Linux server can handle a million threads without much trouble, it really seems like misplaced effort Seems like that would use a lot of memory for all the stacks
Based on this, the default value is 2MB: https://unix.stackexchange.com/questions/127602/default-stac... So that would mean a lot of memory for 1 million threads, 2TB of RAM. But you can change the default. With a 64k stack you'd use up ~68GB of RAM, which doesn't seem like a lot for 1 million threads and 1 million requests happening at the same time.
Tokio 1.0 – async runtime for Rust
251–260 of 422 posts
Re: Tokio 1.0 – async runtime for Rust
#252Earlier quoted context omitted.
Based on this, the default value is 2MB: https://unix.stackexchange.com/questions/127602/default-stac... So that would mean a lot of memory for 1 million threads, 2TB of RAM. But you can change the default. With a 64k stack you'd use up ~68GB of RAM, which doesn't seem like a lot for 1 million threads and 1 million requests happening at the same time.
What "normal-sized Linux server" has 70GB of RAM?
Re: Tokio 1.0 – async runtime for Rust
#253Earlier quoted context omitted.
Based on this, the default value is 2MB: https://unix.stackexchange.com/questions/127602/default-stac... So that would mean a lot of memory for 1 million threads, 2TB of RAM. But you can change the default. With a 64k stack you'd use up ~68GB of RAM, which doesn't seem like a lot for 1 million threads and 1 million requests happening at the same time.
What "normal-sized Linux server" has 70GB of RAM?
Re: Tokio 1.0 – async runtime for Rust
#254Re: Tokio 1.0 – async runtime for Rust
#255Earlier quoted context omitted.
Woah, I didn't know about that. Does this mean Rust only has one maintained runtime now? Namely Tokio.
I think it's rather that smol is "complete" and doesn't need much maintenance.
Re: Tokio 1.0 – async runtime for Rust
#256Earlier quoted context omitted.
> For those that don’t know, on Linux there is^H^H was really no such thing as properly async file system access (eg libc faked it in a similar fashion for aio) That's not quite right - there didn't use to be AIO for buffered filesystem IO and for most operations beyond read/write. But unbuffered reads/writes have been doable asynchronously for quite a long time, via io_submit/libaio. Without falling back to threads.…
> there didn't use to be AIO for buffered filesystem IO Did they change libaio to work without O_DIRECT at some point? Or are you talking about io_uring for async file io?
No, and I don't really forsee that happening at this point.
> Or are you talking about io_uring for async file io?
Yep. io_uring can do async buffered file IO.
Initially, for buffered file IO, everything not in the page cache (e.g. a cache miss read, or a write without a page cache page already existing) was done via kernel threads inside the kernel, but that's being incrementally improved. Now most buffered reads don't need a kernel thread anymore (instead they are submitted during the io_uring_enter, and completed in task context, avoiding a lot of the overhead of "synchronous" execution in a kernel thread).
Re: Tokio 1.0 – async runtime for Rust
#257Earlier quoted context omitted.
No, multithreaded synchronous code is not easier to reason about than async. I think most would agree.
You probably think async code can't have deadlocks like threaded code can. Async is still multi-threaded it's just that the threads are done in user-space and contain an implicit global lock.
Re: Tokio 1.0 – async runtime for Rust
#258I don't really get these modern async APIs. In languages like Javascript I thought they only made sense because JS interpreters are (historically) single-threaded, so you really have no choice but async to express some concepts. Fine. But in Rust you can just spawn threads, share data through channels or mutexes, use OS-provided async IO primitives to poll file descriptors and do event-driven programming etc... I tri…
My understanding from reading along with many of these conversations is that the ultimate goal of the async IO frameworks is to amortize system call costs across multiple IO operations, instead of having >1 per.
I've heard some speculation about system call overhead going up in order to guarantee correctness (for Spectre and Meltdown class scenarios, but also for some other classes of concurrency issues). In which case io_uring is the carrot and system call slowdown the stick.
Re: Tokio 1.0 – async runtime for Rust
#259Earlier quoted context omitted.
How does it handle slow http attacks? If I open 10k TCP connections to your server and drip feed http requests 1 byte at a time on each connection, what happens? You used to be able to easily DOS apache servers this way, because you just needed enough concurrent connections to exhaust its thread pool and then it wouldn't be able to handle any more requests. And then you need a bit rate on each connection just high en…
Yes I use nginx. Yes I know websocket is different.
It's a totally legitimate answer, though, it just made me smile.
Re: Tokio 1.0 – async runtime for Rust
#260Earlier quoted context omitted.
The Rust language provides the async/await syntax, which can turn imperative code into Future objects, but to run those Future objects, you must repeatedly call their poll method. Tokio is the piece of code that calls that method. It does so in a manner such that futures are only polled if able to continue work, and not e.g. waiting for a timer. Besides that it provides lots of utilities for working with async code.
> but to run those Future objects, you must repeatedly call their poll method Oh man. C++'s std::future has the same silliness. I've come to the conclusion that futures/promises are a dumb abstraction.