`maybe_async` and `reqwest` blocking vs non-blocking

I'm writing a crate using maybe_async and reqwest.

Something silly I'm missing is how to conditionally include / use reqwest::Client vs reqwest::blocking::Client according to the is_sync feature flag of maybe_async.

2 Likes

You could use something like cfg-if for that, write your own macro, or do it the vanilla way:

#[cfg(feature = "is_sync")]
use reqwest::blocking::Client;

#[cfg(not(feature = "is_sync"))]
use reqwest::Client;

You must wrap the is_sync feature of maybe_async in your own feature though:

[features]
is_sync = [ "maybe_async/is_sync"]
3 Likes

Features are supposed to be additive, and crates shouldn't break when used with --all-features. Using is_sync for switching between two incompatible APIs goes against that.

Unfortunately, Rust doesn't have an elegant solution to this. All options are bad in some way.

reqwest is fundamentally an async-only library which always requires an async runtime, and its blocking API is only a wrapper around its async core. Because of that, I don't think it even makes sense to try to use the sync API. It doesn't avoid dependency on async. It doesn't switch to any blocking OS APIs. It doesn't make anything more efficient. It's only an extra baggage on top of async-only core.

So I suggest just write async-only code, with async-only API. If someone needs to use it in a blocking context, they can use handle.block_on themselves.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.