To be honest, I need to understand what exactly caused the bug in question in more detail to really answer that. If TcpStream
really does silently truncate the connection when a runtime is dropped, Tokio is at fault. Rusoto may also be at fault, depending on the exact details.
The snippet that @kornel linked is definitely a case of rusoto misusing Tokio, even if it is not necessarily the source of the bug. Creating a new runtime on every call to read
is pretty damn expensive, considering that creating a runtime includes spawning a full thread pool, usually with 8 threads (depending on the number of cpu cores) just to perform a single read
syscall on a TcpStream
.
Generally, I think it is a bad idea to provide the async and blocking apis mixed together in the way rusoto does. The reqwest crate provides a very good example of what I would recommend regarding design of blocking apis to codebases using async/await. If you need to call block_on
directly to use the blocking api of the library, then that library is doing something incorrectly.
It can also be something else, for example I notice that the linked bug has
reader.read_to_string(&mut string);
without any unwrap or question mark on that fallible operation, silently ignoring any errors. The snippet in question does not compile as is, but if that is also the case in the real code, then the author of that code is at fault for ignoring the compiler's #[must_use]
warnings on fallible operations, assuming the read was not silently truncated, but instead returned an actual error.
As for worrying, Tokio and its ecosystem is actually very robust in most cases, and the vast majority of rough edges lie at the boundary between async and sync code. That said, if you avoid the following two things, you should be ok.
- Using Tokio's tools outside of a Tokio runtime.
- Moving IO resources between Tokio runtimes.
Prefer to finish your full IO operation in async code, instead of that half-block_on
, half-blocking IO stuff that rusoto seems to want you to do.