Live data from Hacker News

Tokio 1.0 – async runtime for Rust

tokio.rs

221–230 of 422 posts

Re: Tokio 1.0 – async runtime for Rust

#221

Earlier quoted context omitted.

> when you have a huge number of very small tasks running concurrently because that's generally where OS-driven parallelism tends to suffer but is it such a common scenario Web servers are all about I/O and handling small tasks (requests), and are a perfect use case for asynchronous programming. > That sounds like premature optimization in many situations IMO Maybe in some cases... but then just don't use futures. Ru…

You may want async if you are writing the next nginx, but for most web application servers threading is perfectly fine.

Rust is intended as a systems programming language, it's for people who are writing "the next nginx". It turns out that there are also a bunch of people who want to write webapp servers in Rust, too, but that's never really been the goal.

Re: Tokio 1.0 – async runtime for Rust

#222
post #218

Earlier quoted context omitted.

Yes. There are some difficult technical issues. In practice, borrow checker works less well on async code than threaded code. This is partly why I prefer threading over async in Rust. Look, we went through some enormous effort to make threading good and fun again. Why wouldn't you use threading?

> Why wouldn't you use threading? Because the C10^nK problem where n increases periodically is still a thing?

Green threads.

Re: Tokio 1.0 – async runtime for Rust

#223
post #170

Earlier quoted context omitted.

There are some pretty bad usability problems with most async APIs too. One is they make your functions colored; async functions world best with other async functions while normal blocking functions work best with other blocking functions. They also introduce a lot of noise; putting async/await everywhere doesn't tell you anything interesting. Considering a normal-sized Linux server can handle a million threads withou…

In the Java world, project Loom[1] is hopefully going to end this situation of async code that is hard to use with blocking code. They introduce a concept called Virtual Threads (previously called Fibers, but they are still looking for the perfect name). This will allow for seamless interoperability between blocking and non-blocking code as everything in Java runs on a Thread and Virtual Threads are just a specializa…

Go and Zig already solved the problem. Java will follow soon with Loom, can't wait.

Re: Tokio 1.0 – async runtime for Rust

#224
post #77

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

> when you have a huge number of very small tasks running concurrently because that's generally where OS-driven parallelism tends to suffer but is it such a common scenario Web servers are all about I/O and handling small tasks (requests), and are a perfect use case for asynchronous programming. > That sounds like premature optimization in many situations IMO Maybe in some cases... but then just don't use futures. Ru…

> Web servers are all about I/O and handling small tasks (requests), and are a perfect use case for asynchronous programming.

In principle yes, but in practice I disagree. Due to keep-alive you want to be able to handle many idle connections at the same time, but you rarely want to handle many active connections at the same time.

Example: Whenever you talk to another services (e.g. a database) you need to limit the number of connections you have open. You can't just blindly open a new connection per incoming request. This means that your practical level by parallelism is often bounded by your database. If every request talks to Postgres and you have a connection pool with a limit of 50, then there is nothing to gain by having support for 1000s of "active" connections. You'd rather want Postgres to focus on finishing existing requests than opening new ones.

And once you look into Postgres you'll observe the same thing: There's only limited amount of CPU/IO so there's no point in having 1000s of "active" requests going on at the same time.

Re: Tokio 1.0 – async runtime for Rust

#225
post #8

Can someone explain to a non-rustacean what Tokio introduces that's not part of Rust? It looks like Rust provides the async/await semantics, so I'm guessing this is an event loop and dispatching system?

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.

Re: Tokio 1.0 – async runtime for Rust

#226

Earlier quoted context omitted.

You may want async if you are writing the next nginx, but for most web application servers threading is perfectly fine.

Rust is intended as a systems programming language, it's for people who are writing "the next nginx". It turns out that there are also a bunch of people who want to write webapp servers in Rust, too, but that's never really been the goal .

Eh, so Rust is not for me? I seem to have heard Rust being inclusive and empowering everyone blah blah. I must have misheard.

Re: Tokio 1.0 – async runtime for Rust

#227
post #170

Earlier quoted context omitted.

In the Java world, project Loom[1] is hopefully going to end this situation of async code that is hard to use with blocking code. They introduce a concept called Virtual Threads (previously called Fibers, but they are still looking for the perfect name). This will allow for seamless interoperability between blocking and non-blocking code as everything in Java runs on a Thread and Virtual Threads are just a specializa…

Loom is going to be a game changer. Hopefully they release it soon.

Didn't they start with green threads way back when?

Re: Tokio 1.0 – async runtime for Rust

#228
post #217

Earlier quoted context omitted.

I am not saying that the borrow checker cannot handle locks. Locks work great. (The borrow checker does not understand locks as a special construct, to be extra clear.) Did you read the post I linked? It lays out the details. I am happy to clarify if you don’t get the specifics.

I see now, I misunderstood your original post. You were saying async/await is necessary because futures work badly, not because all the alternatives (i.e. locks) work badly. Sorry, my mistake! Edit to add: futures work badly in every language, so there's no shame in the borrow checker not working with them. Edit 2: But in that case we're back to "why would Rust want async/await over (potentially green) threads with i…

Regarding your edit 2, I linked two talks I have that go over this in great detail elsewhere in this thread.

Re: Tokio 1.0 – async runtime for Rust

#229
post #165

Earlier quoted context omitted.

>Threads, obviously, accomplish the same thing, and arguably more easily. But threads have a performance problem when they must interact heavily. Cross-thread communication is expensive. I didn't know that cross "async" communication was cheaper, that does seem like a good selling point, but what exactly makes it cheaper? After all threads share the same address space, so you can just pass pointers around the same wa…

I think the point is that you can omit atomics in async case, if you are always using async in single thread mode.

Not just atomics, you'd probably need mutexes or rwlocks in a lot of scenarios, and these can become a bottleneck quickly if you don't think it through. Async has the benefit of context switches (handing off execution) being explicit, so you're fine as long as you don't leave any half-updated state before you do an async function call.

Re: Tokio 1.0 – async runtime for Rust

#230

Earlier quoted context omitted.

They're not really the same: you know that an async function may potentially suspend and have other code run before its completion, while a normal function (in the absence of threads and signals) is guaranteed to run atomically, at least as far as your process's memory space is concerned. You also know that the only points at which an async function may suspend are an 'await' statement, and so data invariants that do…

Programmers cannot get threading right, but Rust can.

Rust won't magically make your threaded code blocks right. It can just provide you tools to ensure that memory won't leak. It's just 1/10 of the solution.
Post reply on HN