-
-
Notifications
You must be signed in to change notification settings - Fork 689
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
Fix WASI builds trying to use JS for spawn_local
#2066
Conversation
Wait, how does this work for the EDIT: I guess maybe if you're using it just to serialize data from the server which is synchronous? Or a server functions that is synchronous? Huh. It seems somewhat odd to me to panic at runtime if someone tries to use actual async, but I guess it's better than nothing. |
@gbj Thanks for flagging this. I did some more testing and the news is not encouraging. My original use case was async on the client but synchronous on the server. That worked fine (as did my earlier idea to use However, when I tried a resource getter that was async on the server too - in Spin's case, outbound HTTP - it did indeed panic as you feared. And when I went back to So... I don't actually know how to solve this. Following @diversable's comment in the issue, I will try running the Spin request handler inside a Tokio single-threaded runtime, which isn't a very lovely developer experience, but if it works then I can see if there is a way to make it less intrusive to app developers. Thanks for your caution and for pointing me in the right direction to confirm the problem! |
Glad to see that you & the folks at Fermyon are working on adding this functionality - thanks, @itowlson ! |
Okay, with a bare Tokio runtime, and reusing the standard |
I have indeed run across the fyi: I think full Axum support is going to have to wait until Hyper.rs merges their wasi support (I'm hesitant to provide end users with a dep on a forked hyper crate); in the meantime, I think you're on track with using the single-threaded Tokio rt, even though the dev exp. isn't smooth. if you want to share your current implementation, I can take a look and get back to you with more ideas about how to proceed re: spawn_local issues... ? I think your approach is going to get Leptos to wasi support quicker than mine :) |
Thanks! What I tried was this in the Spin app: #[http_component]
async fn handle(req: IncomingRequest, resp_out: ResponseOutparam) {
let rt = tokio::runtime::Builder::new_current_thread().enable_time().build().unwrap();
let local = tokio::task::LocalSet::new();
rt.block_on(local.run_until(
async move {
handle_what_could_go_wrong(req, resp_out).await
})
);
} with the rest of it as in https://github.com/itowlson/spin-leptos-investigation/tree/counter-isomorphic (except for the Then in leptos/leptos_reactive/src/spawn.rs Line 73 in 4e8c3ac
if #[cfg(all(target_arch = "wasm32", target_os = "wasi"))] {
use crate::Runtime;
let runtime = Runtime::current();
tokio::task::spawn_local(async move {
crate::TASK_RUNTIME.scope(Some(runtime), fut).await
});
} |
2fc4de6
to
859d599
Compare
@gbj Well, I don't know if this is going to meet with your approval, but after the various dead ends discussed above, the only solution I have found is, I'm afraid, Spin-specific. It introduces a Spin SDK dependency into Leptos, which feels nasty outside of the integration crates; but it is optional and is brought in only via a After discussions with the Spin team, the longer goal is to move towards using a Tokio implementation inside the Spin SDK, instead of the hand-rolled executor. This would be beneficial for Spin too, of course, but from the Leptos point of view it would hopefully remove the need to special-case (and would remove that ugly dependency). I don't have a time frame for this, though, and can't make any promises. In the meantime, I've tested this with resources that are both sync and async on the server, and it has worked in both cases. Given the lack of automated coverage, if there's any other testing you'd like me to do, let me know. The apparently unrelated changes to the string concatenation operation in |
Cool! It looks like the Thanks so much for your work on this. |
Signed-off-by: itowlson <[email protected]>
859d599
to
9bfc3dc
Compare
Thanks! I pushed an update to fix the CI error if you wouldn't mind re-approving to run the workflows. |
I think the remaining CI error is a flake installing jq. |
Fixes #2056.
This is a change to the original fix proposed in the issue. After talking to colleagues working on upstream WASI, the recommendation was to poll the future only once, on the basis that if the future were pending at that point,
futures::executor::block_on
would block forever, and it was better to panic with a specific message than to do that.The caveat here is that
spawn_local
is a very low level function. My fix works for the case I ran into, which wascreate_resource
. But ifspawn_local
is used elsewhere for a future that is truly long-running and non-blocking (such as a WASI Preview 2 outbound HTTP request) then this will fail. Hopefully in that case the message will at least point us to the fix that's needed. I don't think this is an issue as yet, but I don't know howspawn_local
really gets used in SSR, so advice is welcome!The risk on top of that caveat is that, as far as I know, the Leptos test suite doesn't currently build for WASI, and I haven't tried to tackle that as part of this PR. So this new case is extremely Works On My Machine. I am not sure how to move forward with testing on WASI I'm afraid.