reqwest icon indicating copy to clipboard operation
reqwest copied to clipboard

`rustls-tls-native-roots` does blocking IO during `.build`

Open chebbyChefNEQ opened this issue 1 year ago • 3 comments

repro Cargo.toml

[package]
name = "test-rs"
version = "0.1.0"
edition = "2021"

[dependencies]
reqwest = { version = "~0.12", default_features = false, features = ["rustls-tls-native-roots"] }
use reqwest::ClientBuilder;

fn main() {
    for _ in 0..10 {
        let start = std::time::Instant::now();
        ClientBuilder::new().build().unwrap();
        println!("built in: {:?}", start.elapsed());
    }
}

this produces the following flamegraph, which include loading certs std::fs.

Not sure what's a nice solution as wrapping the load in tokio::spawn_blocking would introduce a breaking change.

chebbyChefNEQ avatar Sep 27 '24 01:09 chebbyChefNEQ

linux oops forgot the attach the flamegraph

chebbyChefNEQ avatar Sep 27 '24 01:09 chebbyChefNEQ

Peeking in the source, yep, it does load a file from the disk. Thinking more about what exactly it's doing, that's not surprising. I'd recommend trying to only build one or a couple clients and sharing them.

I suppose one option is that you could load the native cert yourself manually (asynchronously), add it as a root certificate to the reqwest builder, and not use the rustls-tls-native-roots feature.

seanmonstar avatar Sep 27 '24 14:09 seanmonstar

loading the certs manually certainly sounds like a good solution. Let me try that, thanks for the suggestion!

chebbyChefNEQ avatar Sep 28 '24 14:09 chebbyChefNEQ

Could ClientBuilder::build be turned into an async fn?

My use case:

Trying to wrap reqwest in a library, and ClientBuilder::build not being an async fn means I'd need a way to avoid blocking the async executor... 😞

teohhanhui avatar Aug 06 '25 15:08 teohhanhui

Could ClientBuilder::build be turned into an async fn?

My use case:

Trying to wrap reqwest in a library, and ClientBuilder::build not being an async fn means I'd need a way to avoid blocking the async executor... 😞

https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html

0x676e67 avatar Aug 06 '25 15:08 0x676e67

@0x676e67 Sure, but that makes my library not sans-IO / non-runtime agnostic. (I know reqwest needs tokio, but I can get around that by strategically using async_compat, right?)

teohhanhui avatar Aug 06 '25 15:08 teohhanhui