Last active
February 27, 2025 04:41
-
-
Save ssrlive/729e19d303aed9ac67d8c3f55690973c to your computer and use it in GitHub Desktop.
learn async for rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// cargo test mytest -- --nocapture | |
// | |
#[cfg(test)] | |
mod tests { | |
use std::{ | |
future::Future, | |
pin::Pin, | |
task::{Context, Poll}, | |
thread::sleep, | |
}; | |
struct ReadFileFuture { | |
counter: usize, | |
} | |
impl Future for ReadFileFuture { | |
type Output = String; | |
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> { | |
println!("ReadFileFuture::poll"); | |
sleep(std::time::Duration::from_secs(1)); | |
_cx.waker().wake_by_ref(); | |
if self.counter > 5 { | |
return Poll::Ready("=== hello from file1 ===".to_string()); | |
} | |
self.counter += 1; | |
Poll::Pending | |
} | |
} | |
#[tokio::test] | |
async fn mytest() { | |
println!("hello before reading"); | |
let h1 = tokio::spawn(async { | |
println!("hello from h1"); | |
let v = ReadFileFuture { counter: 0 }.await; | |
println!("out put from h1: {}", v); | |
}); | |
let h2 = tokio::spawn(async { | |
println!("hello from h2"); | |
let v = read_from_file2().await; | |
println!("out put from h2: {}", v); | |
}); | |
let h3 = tokio::spawn(async { | |
println!("hello from h3"); | |
AsyncTimer::new(std::time::Instant::now() + std::time::Duration::from_secs(2)).await; | |
println!("end h3"); | |
}); | |
let _ = tokio::join!(h1, h2, h3); | |
println!("end reading"); | |
} | |
fn read_from_file2() -> impl Future<Output = String> { | |
async { | |
println!("read_from_file2"); | |
sleep(std::time::Duration::from_secs(2)); | |
"--- hello from file2 ---".to_string() | |
} | |
} | |
pub struct AsyncTimer { | |
expiration: std::time::Instant, | |
} | |
impl AsyncTimer { | |
pub fn new(expiration: std::time::Instant) -> Self { | |
AsyncTimer { expiration } | |
} | |
} | |
impl Future for AsyncTimer { | |
type Output = (); | |
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | |
println!("AsyncTimer::poll"); | |
if self.expiration <= std::time::Instant::now() { | |
Poll::Ready(()) | |
} else { | |
let waker = cx.waker().clone(); | |
let expiration = self.expiration; | |
std::thread::spawn(move || { | |
sleep(expiration - std::time::Instant::now()); | |
waker.wake(); | |
}); | |
Poll::Pending | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment