bytecodealliance / bytecodealliance/StarlingMonkey

WASI incoming HTTP handler can get stuck for JS componets when interleaving (Rust components work)

Open
#321 6 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
C
Stars
288
Forks
57
PR merge metrics
No merged PRs in 30d

Description

For a long time, I wanted to change the execution model of my wasmtime runtimes from being ephemeral and short-lived to being long-lived, i.e. reusing a store to interleave multiple HTTP requests (instead of constructing and destroying requests per state).

I actually had it rolled out at some point to then roll back because it worked for rust components but not for:

* JS components
* and only if the JS component calls a host interface.

To be clear, besides having a shallow understanding of where it locks up, I don't understand what the issue is, e.g. it could be an issue with my host implementations (though it works for rust), it could be an issue with `jco` or seamonkey's js event loop, wasmtime itself, .... 🤷‍♀️. Out of ignorance, I filed the issue here but happy to move it elsewhere 🙏

### Test Case

```sh
git clone https://github.com/trailbaseio/trailbase.git
cd trailbase
git checkout wasm-share-state2
cd crates/wasm-runtime-axum

# Running with the "working" Rust component
cargo run --example standalone -- --path=../../client/testfixture/wasm/wasm_guest_testfixture.wasm
# Will produce an error but the second run of curl won't block up the system.
curl "localhost:3000/addDeletePost"
curl "localhost:3000/addDeletePost"

# Running with the "broken" JS component
cargo run --example standalone -- --path=../../client/testfixture/wasm/wasm_ts_guest_testfixture.wasm
curl "localhost:3000/addDeletePost"
curl "localhost:3000/addDeletePost"
```

Note, the above is running pre-built, checked-in WASM components. Their respective HTTP handler implementations live here:

* https://github.com/trailbaseio/trailbase/blob/wasm-share-state2/client/testfixture/guests/rust/src/lib.rs#L71
* https://github.com/trailbaseio/trailbase/blob/wasm-share-state2/client/testfixture/guests/typescript/src/index.ts#L49

When running curl the second time for the JS component, it's this call to `wasi_incoming_http_handler`: https://github.com/trailbaseio/trailbase/blob/57e912f042e44f313139f99f59bd54ec968fba3b/crates/wasm-runtime-host/src/lib.rs#L354 that gets stuck.

A potential culprit is how I hacked the async host function, I.e. the component-side `query()` sends and outgoing http-request that is intercepted and handled here: https://github.com/trailbaseio/trailbase/blob/57e912f042e44f313139f99f59bd54ec968fba3b/crates/wasm-runtime-host/src/host.rs#L126-L130

(The latter is one of the reasons why I've sat this out so long, I was hoping that WASIp3 may fix my issue, but it seems I keep running into obstacles 🥲 )

### Expected Results

Ideally I would expect the JS component to behave like the Rust component. However, them behaving more consistently would already be an improvement.

### Actual Results

Execution gets stuck.

### Versions and Environment

Wasmtime version or commit: v46
Operating system: debian
Architecture: amd64

Contributor guide

No contributing guide indexed for this repository

Research direction

Reproduce the issue from the wasm-share-state2 branch with crates/wasm-runtime-axum/examples/standalone and the two curl requests, comparing the Rust and TypeScript fixtures. Start at crates/wasm-runtime-host/src/lib.rs around wasi_incoming_http_handler and host.rs around the query handling, then inspect the linked guest handlers. Done means the second JS request no longer gets stuck and its behavior is consistent with the Rust component.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, rust, typescript, wasm
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.