The current-thread scheduler provides a single-threaded future executor. All tasks will be created and executed on the current thread
The supposedly single threaded runtime is used in a different thread through its handle. What is the expected behavior ?
Running the code shows the "inner" work runs on child thread. Doesn't this contradict All tasks will be created and executed on the current thread ?
No. The task is (probably) created on the main thread. But you are creating a new thread. Tokio can't actively prevent you from calling into std and spawning a new thread manually, after all.
it is expected behavior. if you check the document for Handle::block_on, it says:
This runs the given future on the current thread, blocking until it is complete, and yielding its resolved result. Any tasks or timers which the future spawns internally will be executed on the runtime.
When this is used on a current_thread runtime, only the Runtime::block_on method can drive the IO and timer drivers, but the Handle::block_on method cannot drive them. This means that, when using this method on a current_thread runtime, anything that relies on IO or timers will not work unless there is another thread currently calling Runtime::block_on on the same runtime.
try this:
fn main() {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
rt.block_on(async {
let handle = tokio::runtime::Handle::current();
let child = std::thread::Builder::new()
.name("child".to_string())
.spawn(move || {
handle.block_on(async {
handle.spawn(work("inner1"));
work("inner2").await;
})
})
.unwrap();
work("outer").await;
let _ = child.join();
});
// give scheduler some time before exit
rt.block_on(work("final"));
}