Skip to content

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.

⚠️ This MR is still draft because I currently only implemented it for Tokio. I would like some feedback on the current progress before continuing.

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

Merge request reports

Loading