I couldn't agree more. And my conclusion is, as it has been, to stay away from async until we have a sane situation.
I couldn't agree more. And my conclusion is, as it has been, to stay away from async until we have a sane situation.
Is it possible to avoid async with Rust when you use most common 3rd party libraries? such as ones to make API requests, database connectors, date/time, logging, deal with special kind of files etc.? or are we talking "the burden is on the user to set feature flags and carefully choose which crates they import into their projects"?
Is it possible to set up the Rust toolchain to not allow async in a project at all?
instead of reqwest you use ureq crate
> database connectors
can't answer at this time
> date/time
chrono crate has nothing to do with async
> logging
log crate with env_logger crate has nothing to do with async. pushing to something like elasticsearch instead of letting filebeat scrape your stdout is a different story
> deal with special kind of files etc.?
std::fs came first, the async stuff on top that recreate it in an async fashion came later. i'm pretty sure if you are dealing with a big file you can do std::fs with a "stream reader" basically
Asking because I could only find a category for explicitly async crates, not the other way around.. https://crates.io/categories/asynchronous
I just googled "synchronous rust http client" - the top result was a Stack Overflow question where the top (accepted) answer listed ureq as the first option.
(I'd still just use reqwest and Tokio though - practically speaking most of the concerns are non-issues in day-to-day work)
I actually did the opposite recently and replaced reqwest with ureq and managed to drop async and tokio altogether and greatly simplify my library. As a newcomer to Rust I kept getting pointed towards reqwest and tokio when ureq is far simpler.
Not using async or async crates is not recommended since most new or updated high quality crates now use async.
~> cd tmp\
~/tmp> cargo new futures-test
Created binary (application) `futures-test` package
~/tmp> cd futures-test
~/tmp/futures-test> cargo add futures-lite
Updating crates.io index
Adding futures-lite v1.13.0 to dependencies.
Features:
+ alloc
+ fastrand
+ futures-io
+ memchr
+ parking
+ std
+ waker-fn
~/tmp/futures-test> code .
~/tmp/futures-test> open src\main.rs
use futures_lite::future;
fn main() {
future::block_on(async {
println!("Hello world!");
})
}
~/tmp/futures-test> cargo run
Compiling futures-io v0.3.28
Compiling memchr v2.6.3
Compiling pin-project-lite v0.2.13
Compiling fastrand v1.9.0
Compiling waker-fn v1.1.1
Compiling parking v2.1.1
Compiling futures-core v0.3.28
Compiling futures-lite v1.13.0
Compiling futures-test v0.1.0 (C:\Users\steve\tmp\futures-test)
Finished dev [unoptimized + debuginfo] target(s) in 1.74s
Running `target\debug\futures-test.exe`
Hello world!
11 total dependencies.And like, to be clear, "the few hundred dependencies from tokio" is also misleading. A `cargo add tokio --features full` adds 43 dependencies to your Cargo.lock at the time of writing.
There's very much a shiny new thing problem in the rust ecosystem.
It's getting hard.
> Tokio's roots run deep within the ecosystem and it feels like for better or worse we're stuck with it.
Tokio has become a tentacle monster that is suffocating Rust.
Async is fine for webcrap, not good for embedded, and all wrong for multi-threaded game dev. The trouble is, the web back end industry is bigger than the other applications, and is driving Rust towards async. Partly because that's what the Javascript crowd knows.
Personally, I wish the web crowd would use Go. The libraries are better, the goroutine model, which is sort of like async but can block, is better for that, and garbage collection simplifies things. Rust is for hard problems that need to be engineered, where you need more safety than C++ but that level of control.
The "web crowd" leans towards async because most problems at scale where you would reach for Rust are almost always in a situation where they need to concurrently do a million tasks on 8 cpus. It's not because 'thats what the Javascript crowd knows', it's because, since the days of nginx (written in C), its been shown async i/o has better performance.
I don't see a lot of CRUD APIs in Rust - it's almost always database-like systems where the goroutine model and garbage collection cause a headache in terms of either memory usage or latency. I'm not sure if I agree that databases aren't "hard problems that need to be engineered".
That said, the reason Rust focuses so much on the web crowd, is because the majority of people paying the bills are the web companies. The Rust foundations biggest sponsors today are AWS, Google, Huawei, Meta and Microsoft (none of which I would describe as the "Javascript crowd"). AWS isn't hiring Rust engineers to work on game engines.
What I see more of is other industries just don't care about that much Rust.
embassy begs to differ
async/await is really just a syntax for building state machines in a way that resembles regular code. It's compiled down to the same code that you would write by hand anyway (early on it had some bloat in state size but I think it's all fixed now).
And embedded has a lot of state machines!
I had already replied to this article over on lobste.rs
https://lobste.rs/s/iovz9o/state_async_rust
The tl;dr is that I think this entire async concern stuff is ridiculously overblown. I suspect the vast majority of Rust devs, like myself, not only accept the current state as "fine" (couple things to work on) but are very happy with the decisions tokio made.