-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support async thread entry points #10
Comments
Hello! I am currently encountering the same issue as #6 and am wondering if there might be a way to fix the issue without the need for supporting postMessage? Currently I'm planning on doing something like this: fn spawn_thread<F, T>(f: F)
where
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static,
{
if cfg!(target_arch = "wasm32") {
thread::spawn(|| {
f();
wasm_bindgen::throw_str("Cursed hack to keep workers alive. See https://github.com/rustwasm/wasm-bindgen/issues/2945");
});
} else {
thread::spawn(f);
}
} At a minimum it is possible to make it work with the error. I don't see what exactly is stopping wasm_thead from being able to block in worker threads, although I admit I haven't read through the crate's code. |
@Davidster I would rather avoid hacks with throws. So I looked more into this issue and found something stupid simple, the web worker script has a close call after executing closure: https://github.com/chemicstry/wasm_thread/blob/main/src/web_worker.js#L25C11-L25C11, could you test if removing it makes your usecase work? You might need to also remove it from I tested it locally and it seems to work, maybe everyone missed this |
Yes, after posting my comment I read more code and found the close() call. Removing it might indeed fix the issue and I will test it in a few days when I get the chance. I was worried that the close() call was needed to prevent a leak or something, but the browser should be able to clean up workers automatically when they have no more pending tasks, right? I wonder if there's a way I can test it, maybe by spawning a lot of wasm_thread's and checking in the dev tools window to see how many active workers stay alive (not sure if such a tool exists). Thank you for your reply! |
In theory, web workers should terminate automatically when there are no items left in worker's event queue (pending async promises) and main thread has dropped worker handle (can no longer |
I just ran into a very similar issue when running async code with futures_lite::future::block_on in a web worker. The web worker would close before a promise could resolve. I think it might be worth removing the .close(), or at least making it an option and documenting the fact that it not work with any async code in the web worker. |
@adamgerhant could you test it on a new refactored v0.3.0 release? We now have a test for this behavior: Line 102 in 49ae81d
|
I tried with v0.3.0 and found that the close() function has to be removed, and spawn_local has to be used instead of block_on. If the close() is not removed then the thread will be closed before the future can be executed since spawn_local returns immediately. Wasm_thread not working: "after" never gets printed
Wasm_thread fixed: "after" gets printed
This is because block_on does not work with jsFutures, while spawn_local does. This also applies for libraries where a jsFuture is internally awaited, such as with wgpu::Instance::request_adapter, which returns a standard Future, but internally awaits a jsFuture so spawn_local must be used. Ultimately I think the easiest solution is to make the thread close() based on a flag, and document that it will not work with jsFutures if it is enabled. With the current method I dont see any way to tell when the async function finishes, since it is created and run by the user, not wasm_thread. Ideally I think it would be best for wasm_thread to natively support async closures. Maybe this could be done by treating all functions as async futures and running them with spawn_local. This would also allow channels to communicate when the function finishes, and then close the thread at the correct time. |
Yeah the problem here is that |
I added a spawn_async method that spawns the future with spawn_local, and uses a static arc flag that is updated when the function is complete and then used to close the thread. It works well so far, and I'll try create a pull request today. The main problem so far is that I wasnt able to get the join handle properly implemented, but I think that should be possible. Edit: I realized that a single static boolean flag for if the thread should close will not work when there are multiple threads running. I am going to try a new approach with arc's, but it will change the internals a bit. Edit 2: I think I got it fully functional with a static hashmap. I will clean up the code, write a test, and make a pull request |
Async entry points would allow using async channels inside web worker threads.
This feature would probably need a major rewrite as discussed in #8
The text was updated successfully, but these errors were encountered: