Live data from Hacker News

Asynchronous IO in Rust

medium.com

51–60 of 111 posts

Re: Asynchronous IO in Rust

#51
post #45

Earlier quoted context omitted.

The dynamically-allocating portions of the stdlib may panic on OOM, but in an embedded context you're not even linking that code into your program. And you're free to provide an alternative stdlib that bubbles up OOM for those rare occasions where you want to dynamically allocate and you want to be able to do something sane in the face of OOM and you're on a platform that doesn't overcommit.

OOM is an abort, not a panic (contrary to the official docs, interestingly) > you're free to provide an alternative stdlib But like... should you have to? > for those rare occasions In kernel programming, allocation failures are common and handling them is essential. To quote my (very talented) classmate, who actually wrote part of a kernel in Rust: "The only really major issue is with how allocation failure works, w…

> But like... should you have to?

This is the status quo (in all languages) if you're doing embedded work: you lose most of the standard library. Rust goes slightly beyond that default by bundling `core`, which is designed for these environments and serves as a building block on which embedded/bare-metal development can flourish. (Cargo works fine with such things, so one can even distribute alternate standard libraries on crates.io.)

> "The only really major issue is with how allocation failure works, which makes rust a (very) poor choice for real kernel development"

I think this was the result of bravely trying very hard to shoe-horn `std` and the inflexible `box` syntax into a kernel environment, somewhere both are 100% not designed for. The recommended approach is to just use `core` and layer non-`std` libs on top of that.

Re: Asynchronous IO in Rust

#52

Earlier quoted context omitted.

It may not be replaced in the standard library, but mio exists and is what most people use for non-blocking stuff.

1. Stackless coroutines will probably require help from the compiler team (hint hint). It'll be worth it! Think web frameworks with Nginx performance and Rust memory safety. 2. Documentation, stability, portability, quality. I'll keep banging that drum until there's a standard. :) 3. The Mio API is subjectively weird, but I might be missing something.

The first point has been on the radar for quite a while (i.e. years), but it's really non-trivial, and not at all necessary for the core language (hence not a priority for stability) since it's basically just some syntactic niceties over existing functionality.

Re: Asynchronous IO in Rust

#53
post #19

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…

Threads+fine-grained locks sucks. But it wasn't necessarily the threads, so much as the fine-grained locks. I'm talking about threads-the-programming-model, where we don't throw away the gains we made with structured programming. I suppose I ought to get off my duff and finish the blog post that explains exactly what that means, but if you know what structured programming is, that's actually enough to explain what I…

> I am talking about threads the programming model

If parallelism is off the table I would be surprised by any disagreement.I doubt any one finds control inverted style of programming more pleasurable (I.e. Callbacks) than code that looks synchronous but executed async. One thing that does require watching out for is that there are no blocking calls. Green threads, coroutines, fibres seem so much nicer as a programming abstraction. Is this view even contentious?

This does not address parallelism though. These are about exchanging control between stacks of execution, only one such stack is active in an unit. There could be multiple such units though and rub lies in should they synchronize by messages (less buggy) or shared mutable state (at times faster if serialization is expensive. Think Python).

A model that I like is different units of execution ( threads) in a common address space, each hosting coroutines or their ilk with the units sync'ing exclusively by message passing but without the need of serialization because they live in a common address space.

Re: Asynchronous IO in Rust

#54
post #51

Earlier quoted context omitted.

OOM is an abort, not a panic (contrary to the official docs, interestingly) > you're free to provide an alternative stdlib But like... should you have to? > for those rare occasions In kernel programming, allocation failures are common and handling them is essential. To quote my (very talented) classmate, who actually wrote part of a kernel in Rust: "The only really major issue is with how allocation failure works, w…

> But like... should you have to? This is the status quo (in all languages) if you're doing embedded work: you lose most of the standard library. Rust goes slightly beyond that default by bundling `core`, which is designed for these environments and serves as a building block on which embedded/bare-metal development can flourish. (Cargo works fine with such things, so one can even distribute alternate standard librar…

1. In practice most embedded toolchains will give you some of the standard library. A standards compliant C++ freestanding library provides new and delete, for example.

2. The libcore allocator API is marked unstable, so even if you go through the trouble of implementing it, how long will it last?

Re: Asynchronous IO in Rust

#55
post #40

I think a lot of folks think of Network IO when they say Asynchronous IO. That's only half the story, unless you're just building proxies and caches you have to deal with Disk IO at some point in time. And, async disk IO is horrible in every OS / language.

The new async keyword in python looks a lot nicer than what we had before.

Re: Asynchronous IO in Rust

#56
post #36

Earlier quoted context omitted.

Isn't this a rehash of the C10K problem[1] from a decade ago? That was pretty much resolved in favour of single-threading and asynchronous IO, with Nginx and Node.js replacing Apache and Ruby as the platforms that the cool kids use. So, if threads are the way to go today, what has changed in the last 10 years to turn the conventional wisdom on it's head? 64-bit processors and servers with more memory? Hypervisors/con…

No, backwards: the C10k techniques are the solution to the problem "how do I achieve my performance and scaling goals given the characteristics of the OS, languages, tools available to me today?". The current thread (sic) is asking the question "if we can change the language, tools (perhaps the OS too), what's the best approach?". And: I have to counterbalance the assertion that Node.js is in any way good for anythin…

That's exactly the point. So my question remains: if threads are the right answer today, either the C10K folks were wrong or something has changed since then. What?

Re: Asynchronous IO in Rust

#57
post #52

Earlier quoted context omitted.

1. Stackless coroutines will probably require help from the compiler team (hint hint). It'll be worth it! Think web frameworks with Nginx performance and Rust memory safety. 2. Documentation, stability, portability, quality. I'll keep banging that drum until there's a standard. :) 3. The Mio API is subjectively weird, but I might be missing something.

The first point has been on the radar for quite a while (i.e. years), but it's really non-trivial, and not at all necessary for the core language (hence not a priority for stability) since it's basically just some syntactic niceties over existing functionality.

> it's basically just some syntactic niceties over existing functionality.

OK, cool! Can you point us to the existing functionality, or any example of it being used for stackless coroutines?

Re: Asynchronous IO in Rust

#58

Earlier quoted context omitted.

I'm confused. To me, green threads are just an implementation detail. The fact that green threading is being used shouldn't leak into the interface. To take Go for an example, you could perfectly well write a conforming implementation of Go that used 1:1 native threading: it would just have different performance characteristics and things like LockOSThread() would become a no-op. Could you elaborate on what you consi…

This is backwards. Green threading can be an implementation detail, but in languages where it's a key feature, green threads let you write code that would otherwise be incorrect. For example, in a native threading model, it is an awful idea to spawn a thread for every incoming connection on a server. It's the easy way to write it, but it's wrong. With a green threading model, though, that's easy and efficient.

> For example, in a native threading model, it is an awful idea to spawn a thread for every incoming connection on a server. It's the easy way to write it, but it's wrong. With a green threading model, though, that's easy and efficient.

A thread per connection isn't wrong, though. You're begging the question by assuming that green threads are faster than native threads. I'm specifically arguing against that.

Re: Asynchronous IO in Rust

#59

Earlier quoted context omitted.

I'm confused. To me, green threads are just an implementation detail. The fact that green threading is being used shouldn't leak into the interface. To take Go for an example, you could perfectly well write a conforming implementation of Go that used 1:1 native threading: it would just have different performance characteristics and things like LockOSThread() would become a no-op. Could you elaborate on what you consi…

This is backwards. Green threading can be an implementation detail, but in languages where it's a key feature, green threads let you write code that would otherwise be incorrect. For example, in a native threading model, it is an awful idea to spawn a thread for every incoming connection on a server. It's the easy way to write it, but it's wrong. With a green threading model, though, that's easy and efficient.

It was a terrible idea with old OS's and engineers never learned about their schedulers. Many of your favorite systems run at high frequencies on Varnish using one thread per session.

Re: Asynchronous IO in Rust

#60
post #56

Earlier quoted context omitted.

No, backwards: the C10k techniques are the solution to the problem "how do I achieve my performance and scaling goals given the characteristics of the OS, languages, tools available to me today?". The current thread (sic) is asking the question "if we can change the language, tools (perhaps the OS too), what's the best approach?". And: I have to counterbalance the assertion that Node.js is in any way good for anythin…

That's exactly the point. So my question remains: if threads are the right answer today, either the C10K folks were wrong or something has changed since then. What?

Modern operating systems are better at handling many threads.
Post reply on HN