Async Interviews

This is a companion discussion topic for the Async Interviews that I am discussing. As the introductory blog post clarifies, the goal of these interviews is primarily to help answer the question, "Now that async-await is stable, what should we do next?" But it's also just to have fun talking about Async I/O and Rust and exploring what the ecosystem has to offer.

Collected links to the blog posts and videos:

22 Likes

Questions from the audience:

  1. Is all this async/await stuff in Rust as confusing as it is in Python?

  2. Should we even be thinking about async if our use cases don't call for it?

  3. How can we avoid all the complexity of async in the normal case when we don't need it?

I ask because I have just wasted a day of my life trying to get data in through an async API and out through a "normal" API in Python.

I want to have stern words with whoever put that complexity into my life for no good reason.

Sorry if all that seems unduly negative. But this does bug me.

1 Like

I have used async/await extensively in both C# and Typescript. In Typescript it was compiled down to ES5 if your target was not ES6, which supports async directly. These compiler created state machines are amazing when you can't afford a "thread per socket" model OR the complexity of callbacks 3 or 4 levels deep in a single threaded language like JS makes the code insane as you attempt to handle both the expected condition and error condition for each function with a callback.

No. If there is no reason the code you are calling would block (i.e. typically is CPU bound), doing anything with async is a waste of time and elevates complexity for no good reason. It also changes your debugging strategies as you can't simply list the threads and see what is in process.

I really like this question. It looks simple but you can approach it from different viewpoints.

Right now we're all used to sync and consider async as "more complex". But in one or two years time, one might well learn async Rust directly - doing a few async projects and knowing a couple of async crates, not necessarily their sync counterparts. For such a person, it may be reasonable to stay with async for another problem that doesn't require it.

Maybe some people in the Python world are already at this point.

3 Likes

That is a good point.

Back in the day, when we did not have threads in our operating system, if we had an operating system at all, we built cooperative multi-tasking systems. I have had a hand in a few of those. They were a kind of "light weight thread system". Everything worked very well and efficiently. Provided everyone was aware of the frame work they were working in. Much like async.

When I speak of the complexity of async/wait I am comparing to the amazing simplicity of building event driven systems in Javascript, in node.js. Basically you have no choice. That is how everything works (almost). The syntax is dead simple. Even if you are using event handlers and call backs rather than async/await.

That made me chuckle. I only know one Python programmer. That problem with async/await I mentioned above is me trying to fix his code for him. And I am no Python programmer!

1 Like

the second async interview, with @cramertj, is now posted -- I'm going to be posting up the blog post version in pieces, though, because it ran so long :slight_smile:

1 Like

Part 2 from the cramertj interview is available

Part 3 from the cramertj interview is available

Async Interview #3 with @carllerche is available.

@nikomatsakis Thank you so much for these interviews and thank you Alex, Nick, @cramertj and @carllerche for offering your time for these interviews.

I have just finished (I almost wrote rust finished, lol) to read and watch the first interview and it was really interesting. I hope Rust and WASM have a great future together (no pun intended :stuck_out_tongue_winking_eye:).

@nikomatsakis I really like the style of the blog-post-video-combination :blush::

  • Blog: Gives you a high level overview of what the interview will be about
  • Video: Gives you the chance to really dive deep into the topic and see examples along the way

Kudos to you! :tophat:

2 Likes

Async Interview #4 with @skade is available.

Nice lopapeysa!

1 Like

Async Interview #5 with @sfackler is available.

1 Like

Async Interview #6 with @hawkw is available.

1 Like

Should we make the basic traits (e.g., Into, From) async as well?

Async Interview #7 with @withoutboats is available.

6 Likes

Async Interview #7 with @withoutboats is available.

Great conversation on async. While the discussion focused on task::block_on and async fn main, I think the other compelling use case for block_on in std is having #[test] async fn work.

While it's true that main is quite common. I would guess most codebases have a single or two main functions, and in the context of main I have already made some kind of choice of what executor I want to run.

Where as right now if I want to test my async library I need to pull in an executor into my dev dependencies, where I'm not particularly concerned about the executor because the library is supposed to be executor independent.

3 Likes

Agreed that would be useful but its not obvious that block_on is the best semantics for the test harness - which instead could get much better test performance scheduling all of the async tests across a more normal executor. That's why I wouldn't propose having #[test] async fn desugar to a call to block_on.

But just having block_on available so that you can write tests now without depending on an external executor would be a great step forward!

2 Likes

Agreed that would be useful but its not obvious that block_on is the best semantics for the test harness - which instead could get much better test performance scheduling all of the async tests across a more normal executor. That's why I wouldn't propose having #[test] async fn desugar to a call to block_on.

Sure I can see that, though for me test performance isn't really a concern, and testing is generally one area I'm usually willing sacrifice performance concerns for other benefits. I don't know enough about it, but would it be considered breaking for #[test] async fn to use block_on initially and then switch out to a more complicated executor later?

I would worry about blocking the feature on a more complicated executor. As I could see that going on the libtest feature wishlist along with #[bench] and custom test frameworks.

Hello

Thanks for the interview and the transcript. Maybe I'm overacting here, because this is really early stage, but reading it this part makes me worry a little bit:

In short, we would want to permit writing a gen fn (and async gen fn ),

This is starting to look like keyword overuse to me. It's one thing I really dislike in C++, that when you want to write a virtual function you now write something like this:

virtual void do_stuff() const override nothrow ...

In other words, the actual name of the function is oppressed by all these auxiliary information keywords around and it's quite a long thing to write and read.

And I worry this is heading in similar direction:

pub unsafe async gen fn do_stuff(...) {

As I said, this is an early stage so I get this was mostly just a syntax placeholder, but it would be great if some other way was found ‒ not necessarily fully general, but not requiring more annotations. I really prefer the way how the ?/Try trait integrates, that it is implemented for already existing types. I guess it's too late to wish for .await be simply implemented for impl Future or that there was more magic involved so it wouldn't work, but at least an attribute instead of a keyword would make it much more readable to me. Nevertheless, I'd really like not to accumulate more of them, if possible.

2 Likes