There are many to choose from and if they have a certain maturity, the performance differences should be negligible (for
this project, anyway).
What remains are two major things to consider: compatibility to other frameworks and API stability/maintenance.
The former is important because some other libraries come with hard dependencies on - for
example - tokio, so if you picked Bastion, you’d
end up with two async executors and potentially strange side effects.
Both are personal or project specific choices - and for this project it is highly recommended to
use async-std, which provides an abstraction layer over several runtimes (incl.
its own runtime).
Note: Since the crate hyper requires the tokio
runtime, this project uses tokio
from
within async-std
.
You should use the latest version of Rust whenever possible.
Traits can be used as interfaces to provide a production and a testing implementation of something (for example) - and
for modern Rust, this interface can require async
functions.
Until Rust 1.75 async
traits were not supported out of the box and required using an additional
crate: async_trait.
As of Rust 1.75, async
traits are
supported (see Rust Blog).
I’m used to seeing async
calls on blocking operations as network or database queries, not regular processing. Does Rust async
code make better usage of multi-core processors?
CPU-bound applications typically don’t benefit from async
, although the runtime could be multithreaded across
different cores.
crossbeam or other crates help with effective parallel processing.
Tasks that benefit from async
are usually I/O bound and require lots of waiting, such as network or disk I/O.
In the case of this project (series) the calculations are light and using async
to schedule them on a loop can
increase efficiency since we are frequently doing a lot of them, so our cores won’t be idle or overloaded.
If you are considering some heavier processing, check out crossbeam or other crates that provide parallelization features.
Tests require, just as regular code, a runtime to schedule and execute futures.
As async
functions, the return type will always be a Future
type, thus the test runner (cargo
in this case) has to
be able to execute those.
Use an attribute such as tokio::test
, or async_std::test
from the framework of your choosing (async-std
being the
default).