Steve Klabnik is truely an amazing teacher. I bought the book while I was half way through it online. Still haven't unpacked the physical copy yet; but wanted to support him :) At the last chapter now!
@Sam Claus There wasn't a donation button anywhere and besides I do want to have the book in my collection without just having it stored digitally. This is probably the only thing I have bought for myself the last couple of years except for a new pair of shoes. And I might want to enjoy it without having to look at a screen whilst reading as well.
26:37: "There's a really beautiful underlying unified theory of computation that puts all these things together in a wonderful way that I don't have time to explain." Where do I find *that* talk, though? 🙂
Quality content. I started learning Rust one year ago and haven't take a step forward into learning async-await since. I think it's time. Thank you Steve for the talk.
I feel like if I watch this 5,000 more times, I'll be Gandolf awesome.
2 роки тому
What spawn does is it gives a future to the runtime to be executed concurrently with the current running future (either cooperatively within the current thread, or in a separate thread, depending on how you configure your runtime). Meaning, it puts the future in the ready task of the runtime. The #[tokio::main] and Runtime::block_on will block on a single future. When the future finishes, other ready futures won't execute. To execute them, you need to cooperatively (asyc cond var + async mutex, async channel) block the future and let the other futures notify when you can unblock.
At 37:00, on registering a future, why don't we directly pass the future to the reactor instead of passing it to executor first? It's very rare that a future is resolved as soon as it's registered. The first call to poll() will almost always return Pending.
A future that's complete on first poll may actually be very common, depending on what you're doing. For instance there are often error scenarios that can be returned instantly. Or you might be caching results, or have information in memory or remote depending on configuration, etc. And a function that has hundreds of possible execution path of which just on contains an await still needs to be async, so functions higher in the code hierarchy are also generally more likely to execute to completion instantly. But it all depends on the specific program of course...
Thanks for this talk, this is actually very impressive and I like the overall design philosophy a lot! Normally the overhead is pretty big, but this seems like a nice API design to me
2 роки тому
One of the problems with async traits is that trait functions can't return "impls". So what you can do (and what async-trait does) is to return a boxed pined dyn Future.
@@Hector-bj3ls Ah, I didn't realize the dot was intentional in your comment. It appears frequently in typos in UA-cam comments when people miss the space bar or when autocorrect fails. (But if it wasn't clear, I was merely correcting the original English grammatical error in redundantly applying "for" to the word "awaiting.)
17:27 Interesting; C++ is also getting around to separating async call setup and starting execution: ua-cam.com/video/tF-Nz4aRWAM/v-deo.html Also, as a non-Rust programmer, the function of "future::join()" is not at all clear for me from the name.
It is required because every call to .await will execute the logic inside the future and suspend the processing of the rest of the code, futures do nothing unless polled, when it is separate, each future will execute to completion before the next one start. The join will wrap all tasks and act like one future to be polled concurrently.
Cooperative multitasking is just one way of using futures, you can use threads too. For example, you could be processing a bunch of TCP connections in one thread and doing I/O in a separate thread, and polling these two from the third thread. So TCP and I/O would be done in parallel, but multiplexed cooperatively in their own respective threads.
Peoples are still heavily working on implementing the generic associated types feature. But it is not easy to implement, it has way more use cases than just async trait functions.
@@ReedoTV thank you I care. This is a new language and do you develop some application game or whatever will it fit I would usefull to how can it be apply
Not quite. I depends on whether you call await before you create the second future or after. So await delay(5); await delay(5); takes 10 seconds, while const a = delay(5); const b = delay(5); await a; await b; only takes 5.
The main argument he tried to make is, in JS the promise is started before you await it, this is why you can call await on them separately and still have them take the same amount of time. In rust, if you don't await the future it won't get started
@@guibirow Unfortunately Steve didn't fully get it right either. .poll() doesn't get called until .await is called. However in his own timer future the sleep already starts happening as soon as the future and thus the thread is created, which is before ever awaiting it. However the Delay one from the library does indeed only start waiting on the first call to poll.
Steve Klabnik is truely an amazing teacher. I bought the book while I was half way through it online. Still haven't unpacked the physical copy yet; but wanted to support him :) At the last chapter now!
It's really amazing how all of these young people in the Rust Community really care about getting it out into the world for anyone to understand.
@Sam Claus There wasn't a donation button anywhere and besides I do want to have the book in my collection without just having it stored digitally.
This is probably the only thing I have bought for myself the last couple of years except for a new pair of shoes.
And I might want to enjoy it without having to look at a screen whilst reading as well.
I can't believe he's the guy who wrote the book of rust. What a legend 👏👏👏
This talk did an amazing job FINALLY explaining how futures work and how the language implements them. Thank you!
26:37: "There's a really beautiful underlying unified theory of computation that puts all these things together in a wonderful way that I don't have time to explain." Where do I find *that* talk, though? 🙂
Quality content. I started learning Rust one year ago and haven't take a step forward into learning async-await since. I think it's time. Thank you Steve for the talk.
Great job at explaining the key aspects. Thanks for taking the time to do it.
39:40 BRUH
I feel like if I watch this 5,000 more times, I'll be Gandolf awesome.
What spawn does is it gives a future to the runtime to be executed concurrently with the current running future (either cooperatively within the current thread, or in a separate thread, depending on how you configure your runtime). Meaning, it puts the future in the ready task of the runtime.
The #[tokio::main] and Runtime::block_on will block on a single future. When the future finishes, other ready futures won't execute. To execute them, you need to cooperatively (asyc cond var + async mutex, async channel) block the future and let the other futures notify when you can unblock.
20:10 as a node dev, I assumed they would run in sequence (await promise1; await promise2;)
Edit: corrected timestamp.
Ya I think he's wrong. node has the same behavior; you need to await Promise.all(promise1, promise2) the same way you do in rust.
At 37:00, on registering a future, why don't we directly pass the future to the reactor instead of passing it to executor first?
It's very rare that a future is resolved as soon as it's registered. The first call to poll() will almost always return Pending.
Then the reactor would also need to do the stuff involving storing the task, polling it, etc., which is the goal of the executor.
A future that's complete on first poll may actually be very common, depending on what you're doing. For instance there are often error scenarios that can be returned instantly. Or you might be caching results, or have information in memory or remote depending on configuration, etc. And a function that has hundreds of possible execution path of which just on contains an await still needs to be async, so functions higher in the code hierarchy are also generally more likely to execute to completion instantly. But it all depends on the specific program of course...
Thanks for this talk, this is actually very impressive and I like the overall design philosophy a lot!
Normally the overhead is pretty big, but this seems like a nice API design to me
One of the problems with async traits is that trait functions can't return "impls". So what you can do (and what async-trait does) is to return a boxed pined dyn Future.
The title should have been "The talk you've been for.await-ing"
Actually just "The Talk You've Been Await-ing". The "for" is redundant as "to await" means "to wait for".
@@peter9477 No, because the keyword attaches to the future being awaited. So it could have been "(The talk you've been).await-ing"
@@Hector-bj3ls Ah, I didn't realize the dot was intentional in your comment. It appears frequently in typos in UA-cam comments when people miss the space bar or when autocorrect fails. (But if it wasn't clear, I was merely correcting the original English grammatical error in redundantly applying "for" to the word "awaiting.)
Amazing talk, as always, thank you Steve!
Awesome! Rust really looks very cool
Does future::join() take more than 2 inputs?
Like, it's pretty useless otherwise.
What would be the equivalent of Promise.All() in JavaScript?
Web join is a macro like a function take varargs in other language, so yes you can join as much future as you want
And no stateless coroutines in 2022 😞
41:56 I don't see how task is returning to the queue here if future is still in Pending state. Could someone explain it to me?
It seems to be stored in waker created in 10 line and will be waiting for wake up call. But how waker is destroyed if task completed immediately?
Steve, I unreservedly love your puns.
39:46
Random Guy: “So, here’s me face 👨🏻🦳 👈”
Super. Mega. Ultra. Efficient.
17:27 Interesting; C++ is also getting around to separating async call setup and starting execution: ua-cam.com/video/tF-Nz4aRWAM/v-deo.html
Also, as a non-Rust programmer, the function of "future::join()" is not at all clear for me from the name.
It is required because every call to .await will execute the logic inside the future and suspend the processing of the rest of the code, futures do nothing unless polled, when it is separate, each future will execute to completion before the next one start. The join will wrap all tasks and act like one future to be polled concurrently.
it is like fiber cooperative multitasking?
No, it's just asynchronous programming. If you don't know what that means then look it up.
Cooperative multitasking is just one way of using futures, you can use threads too. For example, you could be processing a bunch of TCP connections in one thread and doing I/O in a separate thread, and polling these two from the third thread. So TCP and I/O would be done in parallel, but multiplexed cooperatively in their own respective threads.
It's co-operative multitasking, yes, but it's not based on fibers. Fibers have their own stack, but the tasks here don't.
CloudFlare are doing cool stuff.
So how's the async trait issue now, do we have some sort of solution or ideas for now?
Peoples are still heavily working on implementing the generic associated types feature. But it is not easy to implement, it has way more use cases than just async trait functions.
guys, are futures similar to observables ??
Its rather similar to Promises like he said in the talk.
Observables are more like rust async streams docs.rs/futures/0.3.5/futures/stream/trait.StreamExt.html
The dude at 39:41 escaped
why isnt future::join a macro?
It is macro indeed
I'm just a starting clothing in Raspberry Pi is how can I start learning about today's topic
@@ReedoTV thank you I care. This is a new language and do you develop some application game or whatever will it fit I would usefull to how can it be apply
Ruby goto available as a compile option. #define SUPPORT_JOKE 1
In JS, if you await two promises that take 5 secs each one after the other, it will take 10 secs. future::join() is equivalent to Promise.all().
Not quite. I depends on whether you call await before you create the second future or after.
So
await delay(5);
await delay(5);
takes 10 seconds, while
const a = delay(5);
const b = delay(5);
await a;
await b;
only takes 5.
@@simonthelen5910 Right, because the promise callback is executed as soon as the promise is created.
The main argument he tried to make is, in JS the promise is started before you await it, this is why you can call await on them separately and still have them take the same amount of time.
In rust, if you don't await the future it won't get started
@@guibirow Unfortunately Steve didn't fully get it right either. .poll() doesn't get called until .await is called. However in his own timer future the sleep already starts happening as soon as the future and thus the thread is created, which is before ever awaiting it. However the Delay one from the library does indeed only start waiting on the first call to poll.
Generators = coroutines.
...that's a pretty bad cough.
shouldn't it be the talk you've been awaiting
i_sleep needs Promise.all in js land too