Live data from Hacker News

Tokio 1.0 – async runtime for Rust

tokio.rs

341–350 of 422 posts

Re: Tokio 1.0 – async runtime for Rust

#341
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…

> I guess I'm trying to understand if it's me who's missing something No you’re not. There is a similar situation in Kotlin, which supports coroutines. Makes things more complicated and is often used for very questionable reasons. This is why I’m excited about project Loom, which will use the same old thread abstraction but can be configured to use fibers under the hood instead. Java devs don’t even care that its not…

> Makes things more complicated and is often used for very questionable reasons.

Why is it complicated? Because you didn't bother to learn new API and it is sufficiently different from older one?

Re: Tokio 1.0 – async runtime for Rust

#342

Earlier quoted context omitted.

Since when did Stjepang leave Rust?

He switched to Go. Stjepang is a very smart person and I'm actually quite excited about what he's going to bring to the Go world.

Was there a blogpost? Or when/where was this announced?

Re: Tokio 1.0 – async runtime for Rust

#343
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…

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…

> One is they make your functions colored

I don't get what's so bad about "colored" function. That color is just about the return type of the function.

How do you return an error from a function that does not return a Result? You must call unwrap (panic) or change the colour of your function by changing the return type to Result and fix all the caller.

Similarly, if you want to use a future from a non-async function, you either call `block_on(...)`, or you change the return type to a future by marking the function async.

I don't think it is that bad. That's just the way explicitly typed programming languages work.

Re: Tokio 1.0 – async runtime for Rust

#344
post #281

Earlier quoted context omitted.

Rust doesn't have a runtime. That's part of its awesomeness. That's why it can target microcontrollers. You're probably used to languages with garbage collectors. Having garbage collection forces you to have a "runtime" since that's where the GC code goes. Then more and more stuff accretes onto this unavoidable runtime, and before you know it you're writing Java code...

Um, rust does have a runtime, that's why you don't need to include packages for strings, refcounting, allocation, etc. Anything that has a language keyword should have a default implementation in that runtime, and much like box, ?, !, etc async and await are both language features that I shouldn't need to include from outside of the runtime.

> you don't need to include packages for strings, refcounting, allocation, etc.

Oh, but you do!

These are in std::str, std::rc, and std::alloc, respectively. You're absolutely able to choose not to include these packages, with #![no_std]. That's how rust is able to target platforms like 8-bit microcontrollers with 16kbytes of RAM.

https://rust-embedded.github.io/book/intro/no-std.html

Re: Tokio 1.0 – async runtime for Rust

#345
post #306
post #282

Earlier quoted context omitted.

I also don't get the async hype. Maybe it is undesirable because that often times plain mono-thread synchronous is fast enough, easier to read, easier to debug and safe to handle to a junior ? Not everybody in a team has the same level of expertise. And Rust is not an interpreted language. IMHO, interpreted languages should just drop to a compiled one to keep it KISS. Instead of going the async road, just to discover…

> Maybe it is undesirable because that often times plain mono-thread synchronous is fast enough, easier to read, easier to debug and safe to handle to a junior ? Not everybody in a team has the same level of expertise. Shared-memory concurrency is pretty much always buggy, IME, even if your team thinks they're experts. > And Rust is not an interpreted language. IMHO, interpreted languages should just drop to a compil…

> Shared-memory concurrency is pretty much always buggy, IME, even if your team thinks they're experts.

Writing bug-free shared memory concurrency programs with Go is trivial. Your opinion is based on outdated information.

Re: Tokio 1.0 – async runtime for Rust

#346
post #156

Earlier quoted context omitted.

This, merely, means that the web application code will hold back what Nginx is capable of serving.

If you know that there will be 10k concurrent users in your application, go ahead and use async right from the start. But for the rest of us, simple, blocking code will do just fine and save us a few headaches.

You underestimate how common this use case is. It motivates the Go language, which is much more widely used than Rust.

Re: Tokio 1.0 – async runtime for Rust

#347
post #340
post #146

Earlier quoted context omitted.

I had the same thing initially. The upside of async over a simple event loop is, in my experience, when things become less simple, and you end up with hard-to-read little state machines all over the place. With async, you can have your event loop, but the state machines are handled by the compiler. Code is like threaded code. That can be very convenient. Threads, obviously, accomplish the same thing, and arguably mor…

> the state machines are handled by the compiler I think this is the aspect of modern approaches async which I am most ambivalent about. One of the things I have learned about programming over the past 10 years is that I, as the programmer, really want to own the flow of control of my program. Once I hand that over to some other system, usually in the name of convenience, I will start to have issues which are difficu…

I think the pain you went through with Java is not quite compareable, as the described havoc (and I do really feel your pain here) would not happen like that in Rust, for the reason that you would have to model these things more explicitly. In detail, it sounds like a cascade of implicit null-ness (aka the billion dollar mistake) and weak references. In Rust null (called None) is explicit through the Option type and the Weak type returns exactly that.

More to your point, as I think you were using this as an analogy for the perils of giving up control: Rust's explicitness should entail all the semantics of your program, and hence async Rust makes you model out all the potentially-racy async interactions with Arc, Mutex, etc. The same middle-man (the borrow checker) who watches over your regular ol' sync code's memory-correctness, now expects extra constraints to be upheld for values passing through async-boundaries. And for me the whole point of Rust is that this correctness proof will do a better job than any person could, for any moderately sized program. So this is middle man you'd want between you and the CPU.

That said, your async runtime could definitely do shenanigans that screw up your nicely modeled program, but that would be a bug in that specific runtime. I haven't deeply read Tokio's source and even if I did, making a qualified judgment about it is beyond me.

Re: Tokio 1.0 – async runtime for Rust

#348
post #347
post #340

Earlier quoted context omitted.

> the state machines are handled by the compiler I think this is the aspect of modern approaches async which I am most ambivalent about. One of the things I have learned about programming over the past 10 years is that I, as the programmer, really want to own the flow of control of my program. Once I hand that over to some other system, usually in the name of convenience, I will start to have issues which are difficu…

I think the pain you went through with Java is not quite compareable, as the described havoc (and I do really feel your pain here) would not happen like that in Rust, for the reason that you would have to model these things more explicitly. In detail, it sounds like a cascade of implicit null-ness (aka the billion dollar mistake) and weak references. In Rust null (called None) is explicit through the Option type and…

So I would not say that the borrow checker is a middle-man. The borrow checker does impose constraints on programming, but at the end of the day it's only relevant at compile time, and you still end up with code which maps in a predictable way to the hardware. If you hand me a synchronous rust code, I can imagine, at least in some approximate way, which set of assembly code would be equivalent.

An async runtime is a totally different animal. If you hand me a block of async rust code and ask me how it will execute, the answer I have to give is "it depends on the runtime". This is the disconnect I am talking about.

Re: Tokio 1.0 – async runtime for Rust

#349
post #336
post #332

Earlier quoted context omitted.

But then that is nothing inherent to Rust, it's a choice made by a particular external library. That is probably the worst downside of async, it splits the ecosystem. Reqwest probably tries to offer both choices by hiding one behind the other (although what you describe sounds excessive - running a single task with tokio's single-threaded executor is actually quite lightweight). That split between "sync" and "async"…

> it's a choice made by a particular external library Yeah I think it points to a culture problem. In some ways because dependency management is so easy with Cargo, I think it creates the temptation to just throw in some dependencies to make something work without truly understanding the overall complexity of what you're creating. Something very similar happens in the NodeJS world. > it splits the ecosystem This is s…

Agreed with your point about Cargo. It's a double edged sword.

We absolutely have an NPM/leftpad culture in Rust.

Is that better or worse than C and C++ where dependencies are so painful that you end up reinventing the wheel most of the time? I honestly don't know.

Re: Tokio 1.0 – async runtime for Rust

#350
post #348
post #347

Earlier quoted context omitted.

I think the pain you went through with Java is not quite compareable, as the described havoc (and I do really feel your pain here) would not happen like that in Rust, for the reason that you would have to model these things more explicitly. In detail, it sounds like a cascade of implicit null-ness (aka the billion dollar mistake) and weak references. In Rust null (called None) is explicit through the Option type and…

So I would not say that the borrow checker is a middle-man. The borrow checker does impose constraints on programming, but at the end of the day it's only relevant at compile time, and you still end up with code which maps in a predictable way to the hardware. If you hand me a synchronous rust code, I can imagine, at least in some approximate way, which set of assembly code would be equivalent. An async runtime is a…

Fair distinction, thanks for making it! My async use cases so far have been in a realm where everything modeled was everything I cared about, and those specifics of the runtime didn't become relevant. I wanted to refer to your example because I do see how that is a thing that needs to be explicitly modeled.

I'd be curious to hear about examples where the runtime did or would surprise you!

Post reply on HN