Closed
Description
Version
tokio v1.18.0
Platform
wasm target (wasm_bindgen + wasm_bindgen_test)
Description
See the provided code sample.
When tokio yield_now
is used, the fetch_with_request
never resolves. Both future performs a few steps, the but fetch_with_request never completes when yield_now
is used. If I replace it with wasm_timer::Delay
with a 0 Duration, the fetch works as expected and the download completes with either success or error.
I'd expect to reach the unreachable
part of the code and as both spawn_local are async and I'd expect to have some progress on both future in some of the next microtask tick.
use wasm_bindgen_futures::JsFuture;
use web_sys::{Request, RequestInit, RequestMode};
use wasm_bindgen_test::wasm_bindgen_test as test;
#[test]
async fn yield_bug() {
wasm_logger::init(::wasm_logger::Config::new(log::Level::Trace));
wasm_bindgen_futures::spawn_local(async move {
let mut i = 0;
loop {
let mut opts = RequestInit::new();
opts.method("GET");
opts.mode(RequestMode::Cors);
let url = "https://example.com";
let request = Request::new_with_str_and_init(&url, &opts).unwrap();
let window = web_sys::window().unwrap();
log::trace!("Fetching... {}", i);
match JsFuture::from(window.fetch_with_request(&request)).await {
Ok(_) => log::trace!("OK {}", i),
Err(_) => log::trace!("ERROR {}", i),
};
i += 1;
unreachable!("For some reason we never get here with tokio::task::yield_now()");
}
});
loop {
let mut i = 0;
loop {
if i % 100000 == 0 {
log::trace!("CC {}", i);
}
tokio::task::yield_now().await;
//let _ = wasm_timer::Delay::new(std::time::Duration::from_micros(0)).await;
i += 1;
}
}
}