Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created May 23, 2019 13:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rust-play/1564ff4df01ebffe2423023e978e3a43 to your computer and use it in GitHub Desktop.
Save rust-play/1564ff4df01ebffe2423023e978e3a43 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
extern crate futures; // 0.1.26
extern crate tokio; // 0.1.18
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use std::thread::{sleep, spawn};
use std::time::Duration;
use futures::prelude::*;
#[derive(Clone)]
pub struct Interval {
counter: Arc<AtomicUsize>,
still_running: Arc<AtomicBool>,
}
impl Drop for Interval {
fn drop(&mut self) {
println!("Interval thread shutting down");
self.still_running.store(false, Ordering::SeqCst);
}
}
impl Interval {
pub fn from_millis(millis: u64) -> Interval {
let duration = Duration::from_millis(millis);
let counter = Arc::new(AtomicUsize::new(0));
let counter_clone = counter.clone();
let still_running = Arc::new(AtomicBool::new(true));
let still_running_clone = still_running.clone();
spawn(move || {
println!("Interval thread launched");
while still_running_clone.load(Ordering::SeqCst) {
sleep(duration);
let old = counter_clone.fetch_add(1, Ordering::SeqCst);
println!("Interval thread still alive, value was: {}", old);
}
});
Interval {
counter,
still_running,
}
}
pub fn get_counter(&self) -> usize {
self.counter.load(Ordering::SeqCst)
}
}
pub struct IntervalFuture {
interval: Interval,
last: usize,
}
impl IntervalFuture {
pub fn new(interval: Interval) -> IntervalFuture {
let last = interval.get_counter();
IntervalFuture { interval, last }
}
}
impl Future for IntervalFuture {
type Item = usize;
type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let curr = self.interval.get_counter();
if curr == self.last {
Ok(Async::NotReady)
} else {
self.last = curr;
Ok(Async::Ready(curr))
}
}
}
fn main() {
let interval = Interval::from_millis(500); // half a second
let mut interval_future = IntervalFuture::new(interval);
let duration = std::time::Duration::from_millis(100); // 2 seconds
for i in 1..51 {
println!(">{}", i);
match interval_future.poll() {
Ok(Async::Ready(curr)) => {
println!("Iteration number {}, counter is {}", i, curr);
}
Ok(Async::NotReady) => (),
Err(()) => unreachable!(),
}
std::thread::sleep(duration);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment