Skip to content

Instantly share code, notes, and snippets.

@masonforest
Last active October 16, 2020 17:35
Show Gist options
  • Save masonforest/4174e75f45781e4448a9eb95caf421cb to your computer and use it in GitHub Desktop.
Save masonforest/4174e75f45781e4448a9eb95caf421cb to your computer and use it in GitHub Desktop.
Mining Future
#[macro_use]
extern crate lazy_static;
use async_std::task;
use rand::{
distributions::{Distribution, Standard},
Rng,
};
use std::{
future::Future,
pin::Pin,
sync::{Arc, Mutex},
task::{Context, Poll, Waker},
time::Duration,
};
#[derive(Clone)]
pub struct MiningFuture {
state: Arc<Mutex<(Poll<State>, Option<Waker>)>>,
}
#[derive(Clone, Debug)]
pub enum State {
Mining,
OtherMinerIsMining(String),
}
impl Distribution<State> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> State {
match rng.gen_range(0, 2) {
0 => State::Mining,
_ => State::OtherMinerIsMining("miner2".to_string()),
}
}
}
impl MiningFuture {
pub fn new() -> Self {
let state: Arc<Mutex<(Poll<State>, Option<Waker>)>> =
Arc::new(Mutex::new((Poll::Pending, None)));
MiningFuture { state }
}
async fn choose_next_miner(self) {
let mut state = self.state.lock().unwrap();
state.0 = if rand::random() {
Poll::Ready(rand::random())
} else {
Poll::Pending
};
println!("chose {:?}", state.0);
if let Some(waker) = state.1.take() {
waker.wake()
}
}
}
impl Future for MiningFuture {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut state = self.state.lock().unwrap();
if matches!(state.0, Poll::Ready(State::Mining)) {
Poll::Ready(())
} else {
state.1 = Some(cx.waker().clone());
Poll::Pending
}
}
}
lazy_static! {
pub static ref MINING_FUTURE: MiningFuture = MiningFuture::new();
}
#[async_std::main]
async fn main() {
task::spawn(async {
loop {
task::sleep(Duration::from_secs(1)).await;
MINING_FUTURE.clone().choose_next_miner().await;
}
});
task::block_on(async {
loop {
MINING_FUTURE.clone().await;
println!("processing transactions");
task::sleep(Duration::from_millis(100)).await;
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment