Rust streams and timeouts gotcha

15 points by laplab


kornel

Sometimes one of these tasks will take a particularly long time before getting to the next .await and releasing the control to the runtime.

That’s not how async works! You’re not supposed to be blocking the runtime, and the time between .await points should always be negligible.

tokio::spawn(task1())

If the task1() is blocking, then this is a bad advice. It just dumps this latency-spiking blocking poll on some other random victim that will be sharing the thread/queue with it.

The correct solution is to avoid having long-running blocking code in async functions. When you have to block from inside async code, then spawn_blocking() is the right solution. If spawn_blocking() is too difficult to use (due to borrowing), then at minimum wrap the blocking code in block_in_place() to warn tokio about the problem, and give it a chance to partially mitigate the problem.