Summary
`perry-ext-fastify::event_loop` (`crates/perry-ext-fastify/src/server.rs:332-348`) drains microtasks + Fastify HTTP requests, but never calls `js_run_stdlib_pump` (or `js_stdlib_process_pending` / `js_ws_process_pending` / `js_http_process_pending` / etc.). After `app.listen()` enters this loop, perry-ext-ws / perry-ext-net / perry-ext-http / perry-ext-fetch accept-loop tokio tasks push events to their pending queues forever; nothing drains them on the JS main thread.
Evidence
`crates/perry-ext-fastify/src/server.rs:332-348`:
```rust
fn event_loop(app_handle: Handle, request_rx: &mut mpsc::Receiver) {
loop {
// Drain microtasks queued by previous handler runs.
unsafe {
js_promise_run_microtasks();
}
// Try to receive a request with a 10ms timeout. Keeps the
// event loop responsive without busy-spinning.
let result = match try_recv_with_timeout(request_rx) {
Some(p) => p,
None => continue,
};
process_request(app_handle, result);
}
}
```
The pre-v0.5.572 version still lives in `crates/perry-stdlib/src/fastify/server.rs:270-289` and does the right thing:
```rust
fn event_loop(...) {
...
loop {
// Process any pending stdlib operations (promises, etc.)
unsafe { crate::common::js_stdlib_process_pending() };
// Process any pending microtasks
perry_runtime::js_promise_run_microtasks();
...
}
}
```
The perry-stdlib version pumps `js_stdlib_process_pending` (which fans out to `js_ws_process_pending`, `js_http_process_pending`, `js_net_process_pending`, …). The perry-ext-fastify rewrite (introduced in `97e80d3b feat(perry-ext-{streams,fastify}): refs #466 — port streams + fastify in parallel (v0.5.572)`) dropped that call.
Effect
Any program that imports both `fastify` and `ws` (or `fastify` + raw `net`, or `fastify` + node `http` client to a different host, or `fastify` + outbound `fetch`, …) and benefits from the well-known flip routing `fastify` to perry-ext-fastify will have its perry-ext-* accept-loop events silently dropped while `app.listen()` is running.
Currently masked in our hub by the more upstream codegen-level WS regression (filed separately at #746), which prevents any v0.5.491+ build from delivering WS events at all. The moment that's fixed, this latent pump-bridge bug becomes the next failure.
Suggested fix
Add a pump call at the top of the perry-ext-fastify event loop body — either:
```rust
fn event_loop(app_handle: Handle, request_rx: &mut mpsc::Receiver) {
loop {
// NEW: pump stdlib so perry-ext-ws / perry-ext-net / perry-ext-http
// events that accumulated on tokio workers get dispatched.
unsafe { perry_runtime::stdlib_pump::js_run_stdlib_pump() };
unsafe { js_promise_run_microtasks(); }
let result = match try_recv_with_timeout(request_rx) {
Some(p) => p,
None => continue,
};
process_request(app_handle, result);
}
}
```
…matching what perry-stdlib::fastify already does. `js_run_stdlib_pump` is the right call here since it routes through the pump-FN-pointer mechanism perry-stdlib registers at startup (`js_register_stdlib_pump`), so this stays decoupled from perry-stdlib's internal feature set.
Environment
Discovered while diagnosing #746 against perry v0.5.891 / v0.5.892 on Linux x86_64.
Summary
`perry-ext-fastify::event_loop` (`crates/perry-ext-fastify/src/server.rs:332-348`) drains microtasks + Fastify HTTP requests, but never calls `js_run_stdlib_pump` (or `js_stdlib_process_pending` / `js_ws_process_pending` / `js_http_process_pending` / etc.). After `app.listen()` enters this loop, perry-ext-ws / perry-ext-net / perry-ext-http / perry-ext-fetch accept-loop tokio tasks push events to their pending queues forever; nothing drains them on the JS main thread.
Evidence
`crates/perry-ext-fastify/src/server.rs:332-348`:
```rust
fn event_loop(app_handle: Handle, request_rx: &mut mpsc::Receiver) {
loop {
// Drain microtasks queued by previous handler runs.
unsafe {
js_promise_run_microtasks();
}
}
```
The pre-v0.5.572 version still lives in `crates/perry-stdlib/src/fastify/server.rs:270-289` and does the right thing:
```rust
fn event_loop(...) {
...
loop {
// Process any pending stdlib operations (promises, etc.)
unsafe { crate::common::js_stdlib_process_pending() };
}
```
The perry-stdlib version pumps `js_stdlib_process_pending` (which fans out to `js_ws_process_pending`, `js_http_process_pending`, `js_net_process_pending`, …). The perry-ext-fastify rewrite (introduced in `97e80d3b feat(perry-ext-{streams,fastify}): refs #466 — port streams + fastify in parallel (v0.5.572)`) dropped that call.
Effect
Any program that imports both `fastify` and `ws` (or `fastify` + raw `net`, or `fastify` + node `http` client to a different host, or `fastify` + outbound `fetch`, …) and benefits from the well-known flip routing `fastify` to perry-ext-fastify will have its perry-ext-* accept-loop events silently dropped while `app.listen()` is running.
Currently masked in our hub by the more upstream codegen-level WS regression (filed separately at #746), which prevents any v0.5.491+ build from delivering WS events at all. The moment that's fixed, this latent pump-bridge bug becomes the next failure.
Suggested fix
Add a pump call at the top of the perry-ext-fastify event loop body — either:
```rust
fn event_loop(app_handle: Handle, request_rx: &mut mpsc::Receiver) {
loop {
// NEW: pump stdlib so perry-ext-ws / perry-ext-net / perry-ext-http
// events that accumulated on tokio workers get dispatched.
unsafe { perry_runtime::stdlib_pump::js_run_stdlib_pump() };
}
```
…matching what perry-stdlib::fastify already does. `js_run_stdlib_pump` is the right call here since it routes through the pump-FN-pointer mechanism perry-stdlib registers at startup (`js_register_stdlib_pump`), so this stays decoupled from perry-stdlib's internal feature set.
Environment
Discovered while diagnosing #746 against perry v0.5.891 / v0.5.892 on Linux x86_64.