x1957
Posted on January 22, 2020
I have a situation:
connect to a websocket & send ping message via rest.(It's ridiculous, but the biggest cryptocurrency exchange Binance's websocket api require this).
fn main() {
task::block_on(async {
loop { // loop for handle reconnect
connect to websocket
task::spawn(async move {
loop {
// delay 30 minutes
// rest put
}
}); // send rest ping/pong
read the push message
// when websocket disconnect finish this iteration
}
});
}
The problem is: when iteration finished, the spawn task will run forever.
We can use async-std channel here to recv the stop message and break the loop.
The new problem: When we delay this task, how to get notice that out loop iteration finished?
futures::select solved this problem.
use async_std::sync::{channel, Receiver};
use async_std::task;
use futures::future::{Fuse, FusedFuture, FutureExt};
use futures::select;
use std::time::Duration;
fn main() {
task::block_on(async move {
let mut idx: i32 = 0;
loop {
idx = idx + 1;
let (_s, r) = channel::<i32>(1);
let h = task::spawn(async move {
loop {
let fut = async {
task::sleep(Duration::from_secs(2)).await;
println!("{} do something!", idx);
}.fuse();
let mut fut = Box::pin(fut);
let mut stop = Box::pin(r.recv().fuse());
select! {
_ = fut=> {},
_ = stop => break,
}
}
});
task::sleep(Duration::from_secs(5)).await;
println!("{} exit", idx);
}
});
}
💖 💪 🙅 🚩
x1957
Posted on January 22, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.