Skip to content

Instantly share code, notes, and snippets.

@mrkgnao
Created March 1, 2020 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrkgnao/ebef0e73a3613e1a560b6c3edf4d8a02 to your computer and use it in GitHub Desktop.
Save mrkgnao/ebef0e73a3613e1a560b6c3edf4d8a02 to your computer and use it in GitHub Desktop.
oh so this is how futures work, huh
use futures::prelude::*;
use futures::task::{Context, Poll};
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use tokio::time;
enum Noise {
PollMe,
WakeMe,
}
struct Noisy {
data: u64,
state: Arc<Mutex<Noise>>,
}
impl Noisy {
fn new(t: u64) -> Self {
Self {
data: t,
state: Arc::new(Mutex::new(Noise::PollMe)),
}
}
}
impl Future for Noisy {
type Output = u64;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let should_be_woken;
let mut state = self.state.lock().unwrap();
match *state {
Noise::PollMe => {
println!("polled {:?}", self.data);
should_be_woken = true;
}
Noise::WakeMe => {
println!(" woken {:?}", self.data);
should_be_woken = false;
}
}
if should_be_woken {
*state = Noise::WakeMe;
let waker = cx.waker().clone();
tokio::spawn(async move {
let mut ival = time::interval(time::Duration::from_millis(1000));
ival.tick().await;
ival.tick().await;
waker.wake();
});
Poll::Pending
} else {
Poll::Ready(self.data)
}
}
}
#[tokio::main]
async fn main() {
let a = Noisy::new(0u64);
let b = Noisy::new(1u64);
a.await;
b.await;
let c = Noisy::new(2u64);
let d = Noisy::new(3u64);
future::join(c, d).await;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment