The Talk you’ve been .await-ing for
@steveklabnik
InfoQ.com: News & Community Site
• Over 1,000,000 software developers, architects and CTOs read the site world-
wide every month
• 250,000 senior developers subscribe to our weekly newsletter
• Published in 4 languages (English, Chinese, Japanese and Brazilian
Portuguese)
• Post content from our QCon conferences
• 2 dedicated podcast channels: The InfoQ Podcast, with a focus on
Architecture and The Engineering Culture Podcast, with a focus on building
• 96 deep dives on innovative topics packed as downloadable emags and
minibooks
• Over 40 new content items per week
Watch the video with slide
synchronization on InfoQ.com!
https://www.infoq.com/presentations/
rust-async-await/
Purpose of QCon
- to empower software development by facilitating the spread of
knowledge and innovation
Strategy
- practitioner-driven conference designed for YOU: influencers of
change and innovation in your teams
- speakers and topics driving the evolution and innovation
- connecting and catalyzing the influencers and innovators
Highlights
- attended by more than 12,000 delegates since 2007
- held in 9 cities worldwide
Presented at QCon San Francisco
www.qconsf.com
async fn foo(s: String) -> i32 {
// …
}
fn foo(s: String) -> impl
Future<Output=i32> {
// …
}
Stuff we’re going to talk about
● async/await and Futures
● Generators: the secret sauce
● Tasks, Executors, & Reactors, oh my!
● … maybe async fn in traits
async/await and Futures
Async/await is simpler syntax for Futures
Async/await is simpler syntax for Futures*
A Future represents a value that will exist
sometime in the future
Let’s build a future!
A timer future
● Mutex around a boolean
● Spins up a new thread that sleeps for some
amount of time
● When the thread wakes up, it sets the boolean to
true and ‘wakes up’ the future
● Calls to poll check the boolean to see if we’re
done
Four rules
For using async/await
async fn foo(s: String) -> i32 {
// …
}
fn foo(s: String) -> impl Future<Output=i32> {
// …
}
If you have a
Future<Output=i32> and
you want an i32, use
.await on it
You can only .await
inside of an async fn or
block
To start executing a
Future, you pass it to an
executor
Generators aka stackless coroutines
Generators are not stable
… yet
Futures need to have poll() called over and
over until a value is produced
Generators let you call yield over and over to
get values
async/await is a simpler syntax for a
generator that implements the Future trait
Tasks, Executors, & Reactors
“The event loop”
Task: a unit of work to execute, a chain of Futures
Executor: schedules tasks
Reactor: notifies the executor that tasks are
ready to execute
Interface to the reactor
Executor calls poll, and provides a
context
Let’s build an executor!
async fn foo() {
// …
}
async fn foo() {
// …
}
spawner.spawn(foo())
async fn foo() {
// …
}
spawner.spawn(foo())
Executor
task queue
async fn foo() {
// …
}
spawner.spawn(foo())
Executor
task queue
Calls poll() on
the Future
async fn foo() {
// …
}
spawner.spawn(foo())
Executor
task queue
Calls poll() on
the Future
async fn foo() {
// …
}
spawner.spawn(foo())
Executor
task queue
Calls poll() on
the Future
Future calls
wake() (reactor)
async fn foo() {
// …
}
spawner.spawn(foo())
Executor
task queue
Calls poll() on
the Future
Future calls
wake() (reactor)
A quick aside about Pin<P>
Before a future starts executing, we need to be able to move it around in memory.
(For example, to create a task out of it, we need to move it to the heap)
Once a future starts executing, it must not move in memory.
(otherwise, borrows in the body of the future would become invalid)
When you turn some sort of pointer type into a Pin<P>, you’re promising that what the
pointer to will no longer move.
Box<T> turns into Pin<Box<T>>
There’s an extra trait, “Unpin”, that says “I don’t care about this”, similar to how Copy
says “I don’t care about move semantics.
Let’s build a reactor!
(We’re not gonna build
a reactor)
(We technically did
build a reactor)
Bonus round: async fn in traits
A function is only one
function
A trait is implemented
for many types, and so
is many functions
It gets way more
complicated
It gets way way way
more complicated
Thanks!
@steveklabnik
● https://rust-lang.github.io/async-book
● https://tmandry.gitlab.io/blog/posts/optimizing-await-
1/
● https://smallcultfollowing.com/babysteps/blog/2019/
10/26/async-fn-in-traits-are-hard/
Watch the video with slide
synchronization on InfoQ.com!
https://www.infoq.com/presentations/
rust-async-await/

The Talk You've Been Await-ing For

  • 1.
    The Talk you’vebeen .await-ing for @steveklabnik
  • 2.
    InfoQ.com: News &Community Site • Over 1,000,000 software developers, architects and CTOs read the site world- wide every month • 250,000 senior developers subscribe to our weekly newsletter • Published in 4 languages (English, Chinese, Japanese and Brazilian Portuguese) • Post content from our QCon conferences • 2 dedicated podcast channels: The InfoQ Podcast, with a focus on Architecture and The Engineering Culture Podcast, with a focus on building • 96 deep dives on innovative topics packed as downloadable emags and minibooks • Over 40 new content items per week Watch the video with slide synchronization on InfoQ.com! https://www.infoq.com/presentations/ rust-async-await/
  • 3.
    Purpose of QCon -to empower software development by facilitating the spread of knowledge and innovation Strategy - practitioner-driven conference designed for YOU: influencers of change and innovation in your teams - speakers and topics driving the evolution and innovation - connecting and catalyzing the influencers and innovators Highlights - attended by more than 12,000 delegates since 2007 - held in 9 cities worldwide Presented at QCon San Francisco www.qconsf.com
  • 7.
    async fn foo(s:String) -> i32 { // … } fn foo(s: String) -> impl Future<Output=i32> { // … }
  • 8.
    Stuff we’re goingto talk about ● async/await and Futures ● Generators: the secret sauce ● Tasks, Executors, & Reactors, oh my! ● … maybe async fn in traits
  • 9.
  • 15.
    Async/await is simplersyntax for Futures
  • 16.
    Async/await is simplersyntax for Futures*
  • 17.
    A Future representsa value that will exist sometime in the future
  • 18.
  • 19.
    A timer future ●Mutex around a boolean ● Spins up a new thread that sleeps for some amount of time ● When the thread wakes up, it sets the boolean to true and ‘wakes up’ the future ● Calls to poll check the boolean to see if we’re done
  • 24.
  • 25.
    async fn foo(s:String) -> i32 { // … } fn foo(s: String) -> impl Future<Output=i32> { // … }
  • 26.
    If you havea Future<Output=i32> and you want an i32, use .await on it
  • 27.
    You can only.await inside of an async fn or block
  • 28.
    To start executinga Future, you pass it to an executor
  • 32.
  • 33.
    Generators are notstable … yet
  • 37.
    Futures need tohave poll() called over and over until a value is produced Generators let you call yield over and over to get values async/await is a simpler syntax for a generator that implements the Future trait
  • 38.
  • 39.
  • 40.
    Task: a unitof work to execute, a chain of Futures Executor: schedules tasks Reactor: notifies the executor that tasks are ready to execute
  • 41.
    Interface to thereactor Executor calls poll, and provides a context
  • 42.
  • 43.
    async fn foo(){ // … }
  • 44.
    async fn foo(){ // … } spawner.spawn(foo())
  • 45.
    async fn foo(){ // … } spawner.spawn(foo()) Executor task queue
  • 46.
    async fn foo(){ // … } spawner.spawn(foo()) Executor task queue Calls poll() on the Future
  • 47.
    async fn foo(){ // … } spawner.spawn(foo()) Executor task queue Calls poll() on the Future
  • 48.
    async fn foo(){ // … } spawner.spawn(foo()) Executor task queue Calls poll() on the Future Future calls wake() (reactor)
  • 49.
    async fn foo(){ // … } spawner.spawn(foo()) Executor task queue Calls poll() on the Future Future calls wake() (reactor)
  • 56.
    A quick asideabout Pin<P>
  • 57.
    Before a futurestarts executing, we need to be able to move it around in memory. (For example, to create a task out of it, we need to move it to the heap) Once a future starts executing, it must not move in memory. (otherwise, borrows in the body of the future would become invalid)
  • 58.
    When you turnsome sort of pointer type into a Pin<P>, you’re promising that what the pointer to will no longer move. Box<T> turns into Pin<Box<T>> There’s an extra trait, “Unpin”, that says “I don’t care about this”, similar to how Copy says “I don’t care about move semantics.
  • 59.
  • 60.
    (We’re not gonnabuild a reactor)
  • 61.
  • 62.
    Bonus round: asyncfn in traits
  • 64.
    A function isonly one function A trait is implemented for many types, and so is many functions
  • 67.
    It gets waymore complicated
  • 71.
    It gets wayway way more complicated
  • 75.
    Thanks! @steveklabnik ● https://rust-lang.github.io/async-book ● https://tmandry.gitlab.io/blog/posts/optimizing-await- 1/ ●https://smallcultfollowing.com/babysteps/blog/2019/ 10/26/async-fn-in-traits-are-hard/
  • 76.
    Watch the videowith slide synchronization on InfoQ.com! https://www.infoq.com/presentations/ rust-async-await/