SlideShare a Scribd company logo
1 of 26
Download to read offline
Rust With
async / .await
By Mario A. Santini
Mario A. Santini
a Software Developer
in Telco.
Fast Doesn’t Mean Efficient
Rust is very fast…
...but still have to wait for:
- I/O operation
- Network connections
- Heavy task to complete
Threads are not Enough
Treads are good to long and heavy tasks in parallel
Not enough for I/O bound workload.
You need more effective tools!
Rust was Late to the Party
Concurrent programming was available
just later on Rust,
for a couple of reasons…
Green Thread or not green Thread?
At the very beginning there was green threads in Rust.
They don’t fit well.
So they move on System Thread.
But they miss something...
Concurrent Programming have
multiple solutions
●
Event-Driven with callbacks
●
Coroutines
●
The actor model
●
Async/Await
●
...
Not Every Solution Fits Well
●
Event-Driven with callbacks: data flow and error
propagation is often hard to follow
●
Coroutines: they abstract away low level details that
are important for custom runtime implementors
●
The actor model: it doesn’t provide a full
abstraction, what about flow control and retry logic?
Async / Await
●
Lazy Futures
●
Async is zero-cost
●
No built-in runtime
●
Available on single and multi-thread
●
Reduced CPU and memory overhead for
I/O workload
The Borrow Checker Wasn’t Enough
How do you safely move a struct that
contains references?
And how about self referenced struct?
A Future in Rust
async {
let mut x = [0; 128];
let read_into_buf_fut = read_into_buf(&mut x);
read_into_buf_fut.await;
println!("{:?}", x);
}
struct ReadIntoBuf<'a> {
buf: &'a mut [u8], // points to `x` below
}
struct AsyncFuture {
x: [u8; 128],
read_into_buf_fut: ReadIntoBuf<'what_lifetime?>,
}
You write:
It become:
Just Whatch an Example: a struct
#[derive(Debug)]
struct Test {
a: String,
b: *const String,
}
impl Test {
fn new(txt: &str) -> Self {
Test {
a: String::from(txt),
b: std::ptr::null(),
}
}
fn init(&mut self) {
let self_ref: *const String = &self.a;
self.b = self_ref;
}
fn a(&self) -> &str { &self.a }
fn b(&self) -> &String {
assert!(!self.b.is_null(), "Test::b called
without Test::init being called first");
unsafe { &*(self.b) }
}
}
Just Whatch an Example: the main
fn main() {
let mut test1 = Test::new("test1");
test1.init();
let mut test2 = Test::new("test2");
test2.init();
println!("a: {}, b: {}", test1.a(), test1.b());
println!("a: {}, b: {}", test2.a(), test2.b());
}
$ cargo run
a: test1, b: test1
a: test2, b: test2
If you run it will print:
Just Whatch an Example: the main2
fn main() {
let mut test1 = Test::new("test1");
test1.init();
let mut test2 = Test::new("test2");
test2.init();
println!("a: {}, b: {}", test1.a(), test1.b());
std::mem::swap(&mut test1, &mut test2);
println!("a: {}, b: {}", test2.a(), test2.b());
}
$ cargo run
a: test1, b: test1
a: test1, b: test1
...but now:
All Rust Types are Movable in
Memory
How to check if it is safe to move?
Pin, Unpin, !Unpin
Pin a value,
if the type of the value
Implements Unpin it can be move.
If it implement !Unpin it is guaranteed
that it will not move.
move in memory
The Future Trait
pub trait Future {
type Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}
async fn foo() -> u8 { 5 } // this returns a future
fn bar() -> impl Future<Output = u8> {
// This `async` block results in a type that implements
// `Future<Output = u8>`.
async {
let x: u8 = foo().await; // you have to .await a future
x + 5
}
}
The Future STD Package
pub fn pending<T>() -> Pending<T> // It’s a future that will
// never resolve
pub fn poll_fn<T, F>(f: F) -> PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
pub fn ready<T>(t: T) -> Ready<T>
Streams
async fn sum_with_next(mut stream: Pin<&mut dyn Stream<Item = i32>>) -> i32 {
use futures::stream::StreamExt; // for `next`
let mut sum = 0;
while let Some(item) = stream.next().await {
sum += item;
}
sum
}
async fn jump_around(
mut stream: Pin<&mut dyn Stream<Item = Result<u8, io::Error>>>,
) -> Result<(), io::Error> {
use futures::stream::TryStreamExt; // for `try_for_each_concurrent`
const MAX_CONCURRENT_JUMPERS: usize = 100;
stream.try_for_each_concurrent(MAX_CONCURRENT_JUMPERS, |num| async move {
jump_n_times(num).await?;
report_n_jumps(num).await?;
Ok(())
}).await?;
Ok(())
}
Await in an Async Way
async fn get_book_and_music() -> (Book, Music) {
let book = get_book().await;
let music = get_music().await;
(book, music)
}
async fn get_book_and_music() -> (Book, Music) {
let book_fut = get_book();
let music_fut = get_music();
join!(book_fut, music_fut)
} A `select!` macro is
available
Nothing of What You Saw Until Now
Will Work in Rust
...if you don’t have a Runtime!
What is an Async/.await Runtime
●
Take care to poll Futures / Streams until it
resolve
●
Take care to run Futures / Streams on threads
pool
An Example
// normal Rust main
fn main() {
// write your code here
}
// Tokio Runtime main
#[tokio:main]
async fn main() -> Result<()> {
// write your code here
//…
let my_fut = get_a_fut();
my_fut.await
}
References
●
Rust book: The Rust Programming Language
– (https://doc.rust-lang.org/book/)
●
Rustonomincon
– (https://doc.rust-lang.org/nomicon/)
●
The Async Book ( It’s not complete)
⚠
– (https://rust-lang.github.io/async-book/)
●
Crossbeam
– (https://github.com/crossbeam-rs/crossbeam)
●
Tokio
– (https://tokio.rs/)
●
async-std
– (https://docs.rs/async-std/latest/async_std/ )
●
Jon Gjengset YouTube channel
– (https://www.youtube.com/c/JonGjengset)
●
Rust Playground
– (https://play.rust-lang.org/)
●
Futures
– (https://docs.rs/futures/latest/futures/)
Thank You!
Have any question?
Please go ahead! :)

More Related Content

Similar to Rust With async / .await

assign4assign4_part1bonnie.c This is a file system ben.docx
assign4assign4_part1bonnie.c  This is a file system ben.docxassign4assign4_part1bonnie.c  This is a file system ben.docx
assign4assign4_part1bonnie.c This is a file system ben.docx
festockton
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Yandex
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++
Yandex
 
The State of PHPUnit
The State of PHPUnitThe State of PHPUnit
The State of PHPUnit
Edorian
 

Similar to Rust With async / .await (20)

assign4assign4_part1bonnie.c This is a file system ben.docx
assign4assign4_part1bonnie.c  This is a file system ben.docxassign4assign4_part1bonnie.c  This is a file system ben.docx
assign4assign4_part1bonnie.c This is a file system ben.docx
 
Geeks Anonymes - Le langage Go
Geeks Anonymes - Le langage GoGeeks Anonymes - Le langage Go
Geeks Anonymes - Le langage Go
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
 
Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018Mario Fusco - Lazy Java - Codemotion Milan 2018
Mario Fusco - Lazy Java - Codemotion Milan 2018
 
Lazy java
Lazy javaLazy java
Lazy java
 
Lazy Java
Lazy JavaLazy Java
Lazy Java
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
 
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
 
(Slightly) Smarter Smart Pointers
(Slightly) Smarter Smart Pointers(Slightly) Smarter Smart Pointers
(Slightly) Smarter Smart Pointers
 
AMC Minor Technical Issues
AMC Minor Technical IssuesAMC Minor Technical Issues
AMC Minor Technical Issues
 
为什么 rust-lang 吸引我?
为什么 rust-lang 吸引我?为什么 rust-lang 吸引我?
为什么 rust-lang 吸引我?
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++
 
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel ZikmundNDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
 
Arduino programming of ML-style in ATS
Arduino programming of ML-style in ATSArduino programming of ML-style in ATS
Arduino programming of ML-style in ATS
 
The State of PHPUnit
The State of PHPUnitThe State of PHPUnit
The State of PHPUnit
 
The State of PHPUnit
The State of PHPUnitThe State of PHPUnit
The State of PHPUnit
 
Making a Process
Making a ProcessMaking a Process
Making a Process
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
 
Gevent be or not to be
Gevent be or not to beGevent be or not to be
Gevent be or not to be
 
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
 

More from Mario Alexandro Santini

More from Mario Alexandro Santini (9)

A Safe Dock for our Programs
A Safe Dock for our ProgramsA Safe Dock for our Programs
A Safe Dock for our Programs
 
Rust_Threads.pdf
Rust_Threads.pdfRust_Threads.pdf
Rust_Threads.pdf
 
The_Borrow_Checker.pdf
The_Borrow_Checker.pdfThe_Borrow_Checker.pdf
The_Borrow_Checker.pdf
 
Vuejs
VuejsVuejs
Vuejs
 
The Rust Programming Language
The Rust Programming LanguageThe Rust Programming Language
The Rust Programming Language
 
Introduction to typescript
Introduction to typescriptIntroduction to typescript
Introduction to typescript
 
The myth of the small script
The myth of the small scriptThe myth of the small script
The myth of the small script
 
Docker jug taa
Docker   jug taaDocker   jug taa
Docker jug taa
 
Lambda architecture
Lambda architectureLambda architecture
Lambda architecture
 

Recently uploaded

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Recently uploaded (20)

Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 

Rust With async / .await

  • 1. Rust With async / .await By Mario A. Santini
  • 2. Mario A. Santini a Software Developer in Telco.
  • 3. Fast Doesn’t Mean Efficient Rust is very fast… ...but still have to wait for: - I/O operation - Network connections - Heavy task to complete
  • 4. Threads are not Enough Treads are good to long and heavy tasks in parallel Not enough for I/O bound workload. You need more effective tools!
  • 5. Rust was Late to the Party Concurrent programming was available just later on Rust, for a couple of reasons…
  • 6. Green Thread or not green Thread? At the very beginning there was green threads in Rust. They don’t fit well. So they move on System Thread. But they miss something...
  • 7. Concurrent Programming have multiple solutions ● Event-Driven with callbacks ● Coroutines ● The actor model ● Async/Await ● ...
  • 8. Not Every Solution Fits Well ● Event-Driven with callbacks: data flow and error propagation is often hard to follow ● Coroutines: they abstract away low level details that are important for custom runtime implementors ● The actor model: it doesn’t provide a full abstraction, what about flow control and retry logic?
  • 9. Async / Await ● Lazy Futures ● Async is zero-cost ● No built-in runtime ● Available on single and multi-thread ● Reduced CPU and memory overhead for I/O workload
  • 10. The Borrow Checker Wasn’t Enough How do you safely move a struct that contains references? And how about self referenced struct?
  • 11. A Future in Rust async { let mut x = [0; 128]; let read_into_buf_fut = read_into_buf(&mut x); read_into_buf_fut.await; println!("{:?}", x); } struct ReadIntoBuf<'a> { buf: &'a mut [u8], // points to `x` below } struct AsyncFuture { x: [u8; 128], read_into_buf_fut: ReadIntoBuf<'what_lifetime?>, } You write: It become:
  • 12. Just Whatch an Example: a struct #[derive(Debug)] struct Test { a: String, b: *const String, } impl Test { fn new(txt: &str) -> Self { Test { a: String::from(txt), b: std::ptr::null(), } } fn init(&mut self) { let self_ref: *const String = &self.a; self.b = self_ref; } fn a(&self) -> &str { &self.a } fn b(&self) -> &String { assert!(!self.b.is_null(), "Test::b called without Test::init being called first"); unsafe { &*(self.b) } } }
  • 13. Just Whatch an Example: the main fn main() { let mut test1 = Test::new("test1"); test1.init(); let mut test2 = Test::new("test2"); test2.init(); println!("a: {}, b: {}", test1.a(), test1.b()); println!("a: {}, b: {}", test2.a(), test2.b()); } $ cargo run a: test1, b: test1 a: test2, b: test2 If you run it will print:
  • 14. Just Whatch an Example: the main2 fn main() { let mut test1 = Test::new("test1"); test1.init(); let mut test2 = Test::new("test2"); test2.init(); println!("a: {}, b: {}", test1.a(), test1.b()); std::mem::swap(&mut test1, &mut test2); println!("a: {}, b: {}", test2.a(), test2.b()); } $ cargo run a: test1, b: test1 a: test1, b: test1 ...but now:
  • 15.
  • 16. All Rust Types are Movable in Memory How to check if it is safe to move?
  • 17. Pin, Unpin, !Unpin Pin a value, if the type of the value Implements Unpin it can be move. If it implement !Unpin it is guaranteed that it will not move. move in memory
  • 18. The Future Trait pub trait Future { type Output; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>; } async fn foo() -> u8 { 5 } // this returns a future fn bar() -> impl Future<Output = u8> { // This `async` block results in a type that implements // `Future<Output = u8>`. async { let x: u8 = foo().await; // you have to .await a future x + 5 } }
  • 19. The Future STD Package pub fn pending<T>() -> Pending<T> // It’s a future that will // never resolve pub fn poll_fn<T, F>(f: F) -> PollFn<F> where F: FnMut(&mut Context<'_>) -> Poll<T>, pub fn ready<T>(t: T) -> Ready<T>
  • 20. Streams async fn sum_with_next(mut stream: Pin<&mut dyn Stream<Item = i32>>) -> i32 { use futures::stream::StreamExt; // for `next` let mut sum = 0; while let Some(item) = stream.next().await { sum += item; } sum } async fn jump_around( mut stream: Pin<&mut dyn Stream<Item = Result<u8, io::Error>>>, ) -> Result<(), io::Error> { use futures::stream::TryStreamExt; // for `try_for_each_concurrent` const MAX_CONCURRENT_JUMPERS: usize = 100; stream.try_for_each_concurrent(MAX_CONCURRENT_JUMPERS, |num| async move { jump_n_times(num).await?; report_n_jumps(num).await?; Ok(()) }).await?; Ok(()) }
  • 21. Await in an Async Way async fn get_book_and_music() -> (Book, Music) { let book = get_book().await; let music = get_music().await; (book, music) } async fn get_book_and_music() -> (Book, Music) { let book_fut = get_book(); let music_fut = get_music(); join!(book_fut, music_fut) } A `select!` macro is available
  • 22. Nothing of What You Saw Until Now Will Work in Rust ...if you don’t have a Runtime!
  • 23. What is an Async/.await Runtime ● Take care to poll Futures / Streams until it resolve ● Take care to run Futures / Streams on threads pool
  • 24. An Example // normal Rust main fn main() { // write your code here } // Tokio Runtime main #[tokio:main] async fn main() -> Result<()> { // write your code here //… let my_fut = get_a_fut(); my_fut.await }
  • 25. References ● Rust book: The Rust Programming Language – (https://doc.rust-lang.org/book/) ● Rustonomincon – (https://doc.rust-lang.org/nomicon/) ● The Async Book ( It’s not complete) ⚠ – (https://rust-lang.github.io/async-book/) ● Crossbeam – (https://github.com/crossbeam-rs/crossbeam) ● Tokio – (https://tokio.rs/) ● async-std – (https://docs.rs/async-std/latest/async_std/ ) ● Jon Gjengset YouTube channel – (https://www.youtube.com/c/JonGjengset) ● Rust Playground – (https://play.rust-lang.org/) ● Futures – (https://docs.rs/futures/latest/futures/)
  • 26. Thank You! Have any question? Please go ahead! :)