Skip to content

Instantly share code, notes, and snippets.

@ssrlive
Last active February 27, 2025 04:41
Show Gist options
  • Select an option

  • Save ssrlive/729e19d303aed9ac67d8c3f55690973c to your computer and use it in GitHub Desktop.

Select an option

Save ssrlive/729e19d303aed9ac67d8c3f55690973c to your computer and use it in GitHub Desktop.

Revisions

  1. ssrlive revised this gist Feb 27, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion learn-async.rs
    Original file line number Diff line number Diff line change
    @@ -74,7 +74,7 @@ mod tests {
    type Output = ();
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
    println!("AsyncTimer::poll");
    if self.expiration < std::time::Instant::now() {
    if self.expiration <= std::time::Instant::now() {
    Poll::Ready(())
    } else {
    let waker = cx.waker().clone();
  2. ssrlive revised this gist Feb 26, 2025. No changes.
  3. ssrlive revised this gist Feb 26, 2025. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions learn-async.rs
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,7 @@
    //
    // cargo test mytest -- --nocapture
    //

    #[cfg(test)]
    mod tests {
    use std::{
  4. ssrlive created this gist Feb 26, 2025.
    86 changes: 86 additions & 0 deletions learn-async.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,86 @@
    #[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
    }
    }
    }
    }