I see two solid points here: 1. It's not reasonable to expect the application layer to carefully partition its work into "I/O heavy" and "CPU heavy" parts. 2. It's not reasonable to queue up an arbitrary amount of work without back-pressure. I haven't used Tokio much, but if it falls prey to these pitfalls, it would make me pause before adopting it. I think there are probably ways of using Rust async that don't fall…
If your application has both of these and doesn't partition them, you already have a fundamental flaw in your application architecture. Every serious piece of software does this, from web GUIs, to servers, all the way to video games.
> It's not reasonable to queue up an arbitrary amount of work without back-pressure
Absolutely, which is why we use pull-futures instead of push-futures, across the entire rust ecosystem. Creating unbounded queues in Tokio requires a fair bit of error on the part of the programmer