Draft: sleepfuture-reset: Create new SleepFuture trait with reset method
This MR resolves: #2176
We want a SleepFuture trait with reset method so we can change the expiration time of the current future without the need to create a new future. This could be handy in e.g the padding implementation. In maybenot_padding.rs:L903 we can see where this would be useful.
I placed demo-codes for each runtime in arti/examples, all seemed to run fine.
ℹ️ Demo for Tokio
use anyhow::Result;
use tor_rtcompat::{SleepProvider, SleepFuture};
use arti_client::{TorClient, TorClientConfig};
#[tokio::main]
async fn main() -> Result<()> {
let tor_client = TorClient::create_bootstrapped(TorClientConfig::default()).await?;
let rt = tor_client.runtime();
println!("Set sleep for 5 seconds...");
let mut sleep = std::pin::pin!(rt.sleep(std::time::Duration::from_secs(5)));
println!("Reset sleep to 15 seconds (without creating new future)...");
let new_deadline = rt.now() + std::time::Duration::from_secs(15);
sleep.as_mut().reset(new_deadline.into());
println!("Sleeping for 15 seconds...");
sleep.await;
println!("Awake after 15 seconds!");
Ok(())
}
[package]
name = "sleepfuture-reset-example"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1.0.97"
arti-client = { path = "../../crates/arti-client" }
tokio = { version = "1", features = ["macros", "rt-multi-thread", "sync"] }
tor-rtcompat = { path = "../../crates/tor-rtcompat" }
ℹ️ Demo for Smol
use anyhow::Result;
use tor_rtcompat::{SleepProvider, SleepFuture, smol::SmolNativeTlsRuntime};
use arti_client::{TorClient, TorClientConfig};
fn main() -> Result<()> {
smol::block_on(async {
let runtime = SmolNativeTlsRuntime::create().unwrap();
let tor_client = TorClient::with_runtime(runtime.clone())
.config(TorClientConfig::default())
.create_bootstrapped()
.await?;
let rt = tor_client.runtime();
println!("Set sleep for 5 seconds...");
let mut sleep = rt.sleep(std::time::Duration::from_secs(5));
println!("Reset sleep to 15 seconds (without creating new future)...");
let new_deadline = rt.now() + std::time::Duration::from_secs(15);
std::pin::Pin::new(&mut sleep).reset(new_deadline.into());
println!("Sleeping for 15 seconds...");
sleep.await;
println!("Awake after 15 seconds!");
Ok(())
})
}
[package]
name = "sleepfuture-reset-example"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1.0.97"
arti-client = { path = "../../crates/arti-client", features = ["smol"] }
smol = "2.0.2"
tor-rtcompat = { path = "../../crates/tor-rtcompat" }
ℹ️ Demo for async-std
use anyhow::Result;
use tor_rtcompat::{SleepProvider, SleepFuture, async_std::AsyncStdNativeTlsRuntime};
use arti_client::{TorClient, TorClientConfig};
#[async_std::main]
async fn main() -> Result<()> {
let runtime = AsyncStdNativeTlsRuntime::create().unwrap();
let tor_client = TorClient::with_runtime(runtime.clone())
.config(TorClientConfig::default())
.create_bootstrapped()
.await?;
let rt = tor_client.runtime();
println!("Set sleep for 5 seconds...");
let mut sleep = rt.sleep(std::time::Duration::from_secs(5));
println!("Reset sleep to 15 seconds (with emulating resetting current future)...");
let new_deadline = rt.now() + std::time::Duration::from_secs(15);
std::pin::Pin::new(&mut sleep).reset(new_deadline.into());
println!("Sleeping for 15 seconds...");
sleep.await;
println!("Awake after 15 seconds!");
Ok(())
}
[package]
name = "sleepfuture-reset-example"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1.0.97"
arti-client = { path = "../../crates/arti-client", features = ["async-std"] }
async-std = { version = "1.13", features = ["attributes"] }
tor-rtcompat = { path = "../../crates/tor-rtcompat" }
Edited by Niel Duysters