I have a Rust async server based on the Tokio runtime. It has to process a mix of latency-sensitive I/O-bound requests, and heavy CPU-bound requests.
I don't want to let the CPU-bound tasks monopolize the Tokio runtime and starve the I/O bound tasks, so I'd like to offload the CPU-bound tasks to a dedicated, isolated threadpool (isolation is the key here, so spawn_blocking/block_in_place on one shared threadpool are insufficient). How can I create such a threadpool in Tokio?
A naive approach of starting two runtimes runs into an error:
thread 'tokio-runtime-worker' panicked at 'Cannot start a runtime from within a runtime. This happens because a function (like
block_on) attempted to block the current thread while the thread is being used to drive asynchronous tasks.'
use tokio; // 0.2.20 fn main() { let mut main_runtime = tokio::runtime::Runtime::new().unwrap(); let cpu_pool = tokio::runtime::Builder::new().threaded_scheduler().build().unwrap(); let cpu_pool = cpu_pool.handle().clone(); // this is the fix/workaround! main_runtime.block_on(main_runtime.spawn(async move { cpu_pool.spawn(async {}).await })) .unwrap().unwrap(); } Can Tokio allow two separate runtimes? Is there a better way to create an isolated CPU pool in Tokio?
block_in_place, but it doesn't give isolation guarantee I'm looking for.