reqwest
reqwest copied to clipboard
`rustls-tls-native-roots` does blocking IO during `.build`
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.
oops forgot the attach the flamegraph
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.
loading the certs manually certainly sounds like a good solution. Let me try that, thanks for the suggestion!
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... 😞
Could
ClientBuilder::buildbe turned into anasync fn?My use case:
Trying to wrap
reqwestin a library, andClientBuilder::buildnot being anasync fnmeans I'd need a way to avoid blocking the async executor... 😞
https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html
@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?)