Skip to content

Instantly share code, notes, and snippets.

@itn3000
Created October 26, 2022 02:55
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 itn3000/5d7e7872588c310be943c91a7598e338 to your computer and use it in GitHub Desktop.
Save itn3000/5d7e7872588c310be943c91a7598e338 to your computer and use it in GitHub Desktop.
rust tokio with cancellation token loop test
[package]
name = "tokiotest"
version = "0.1.0"
authors = ["itn3000"]
edition = "2018"
[dependencies]
tokio = { version = "1.21",features = [
"rt",
"rt-multi-thread",
"time",
"macros",
"io-std",
"io-util",
]}
tokio-util = "0.7"
futures = "0.3"
anyhow = "1.0"
//
use std::time::Duration;
use tokio_util::sync::CancellationToken;
use anyhow::Result;
use tokio::io::AsyncBufReadExt;
#[allow(dead_code)]
pub async fn cstokentest() -> Result<()> {
let cs = CancellationToken::new();
let c1 = cs.child_token();
let c2 = cs.child_token();
let sw = std::time::Instant::now();
let t1 = tokio::task::spawn(async move {
tokio::select!{
val = tokio::time::sleep(Duration::from_secs(1)) => {
println!("t1:s, {:?}", sw.elapsed());
0
},
val = c1.cancelled() => {
println!("t1:c, {:?}", sw.elapsed());
1
}
}
});
println!("a:{:?}", sw.elapsed());
let t2 = tokio::task::spawn(async move {
tokio::select!{
val = tokio::time::sleep(Duration::from_secs(1)) => {
println!("t2:s, {:?}", sw.elapsed());
2
},
val = c2.cancelled() => {
println!("t2:s, {:?}", sw.elapsed());
3
}
}
});
println!("b:{:?}", sw.elapsed());
tokio::time::sleep(Duration::from_millis(2000)).await;
println!("c:{:?}", sw.elapsed());
cs.cancel();
let (r1, r2) = futures::future::join(t1, t2).await;
println!("d:{:?}", sw.elapsed());
println!("{}, {}", r1?, r2?);
Ok(())
}
#[allow(dead_code)]
pub async fn cstoken_loop() -> Result<()> {
let cs = CancellationToken::new();
let c1 = cs.child_token();
let sw = std::time::Instant::now();
let t1 = tokio::spawn(async move {
while !c1.is_cancelled() {
let v = tokio::select!(
val = tokio::time::sleep(Duration::from_millis(1000)) => 0,
val = c1.cancelled() => 1,
);
println!("return value is {},{}", v, sw.elapsed().as_millis());
if v == 1 {
break;
}
}
println!("loop end");
});
let t2 = tokio::spawn(async move {
let si = tokio::io::stdin();
let mut reader = tokio::io::BufReader::new(si);
let mut s = String::new();
let _ = match reader.read_line(&mut s).await {
Ok(v) => v,
Err(e) => return Err(e),
};
cs.cancel();
Ok(())
});
let (r1, r2) = futures::join!(t1, t2);
println!("{}", r1.is_ok());
println!("{:?}", r2?);
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment