voidzero-dev / voidzero-dev/vite-plus

Dev server restart wedges permanently under @cloudflare/vite-plugin when a request straddles the restart (bundled-dev/rolldown pipeline implicated)

オープン
#2,481 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
Rust
スター
5.8k
フォーク
262
平均マージ
23時間 18分
マージ済み PR(30日)
139

説明

### Versions

vite-plus 0.2.5 (Vite core 8.1.5), @cloudflare/vite-plugin 1.52.1, wrangler 4.123.0, node 24.x, darwin-arm64 (also reproduces on GitHub Actions macos-14)

### Summary

Cross-filed with cloudflare/workers-sdk#15241 (full mechanism and OS-level evidence there). Filing here because the permanent wedge reproduces **only** when the Vite+/rolldown dev pipeline is active — a plain-Vite scaffold at identical pins does not wedge in 8 escalating-fidelity trials — so vite-plus is a co-suspect by elimination.

When `server.restart()` runs while an HTTP request is in flight, the cloudflare plugin's post-swap handshake (`fetchWorkerExportTypes` → `miniflare.dispatchFetch`) never resolves: the straddling request is left permanently in-flight inside workerd (CLOSE_WAIT entry socket in 7/7 hangs), and the export-types fetch wedges behind it. `configureServer` never returns, `server.restart()` never settles, and the old server is never closed. Traffic during restart is necessary and sufficient (hang 9/9 with a poll loop; clean 14/14 without).

### Why vite-plus specifically

- The wedged node process runs rolldown worker threads at hang time (`sample` captures available) — i.e. the bundled-dev serving path, not plain per-module transform.
- Plain Vite + the same cloudflare plugin, same options swap, same D1 binding, same tight polling: the mid-swap `fetch failed` abort signature reproduces, but the export-types fetch still resolves (~3s). Under vite-plus it never resolves.
- The in-flight `JsRpcTarget` frames in every wedged workerd sample are consistent with a straddling request holding a multi-roundtrip module-runner/bundle RPC open across the Miniflare options swap — plausibly the bundled-dev "keep Miniflare and related resources alive during mid-serve builds" behavior interacting with a client-aborted request that workerd never cancels.

### Repro

Deterministic 9/9 via a Pioneer framework scaffold (github.com/find-how/pioneer.find.how — `pioneer new`, `pioneer dev`, curl poll loop, config-triggered restart). Trial harness and captured evidence (debuglogs, `sample`, `lsof`) available on request; happy to help reduce further.

### Downstream mitigation in place

We now 503-gate incoming requests during restart, which removes the trigger — but the non-settling handshake under bundled-dev remains reproducible upstream behavior worth a cancellation/drain fix at the source.

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

bundled-dev/rolldown の dev-server パスから開始し、server.restart()、configureServer、そして fetchWorkerExportTypes → miniflare.dispatchFetch のハンドシェイクを追跡します。リクエストが再起動をまたぐ状況で、Pioneer scaffold と curl のポーリングループを使って再現し、その後 plain Vite と比較します。ハンドシェイクが収束し、下流の 503 gate を必要とせずに古いサーバーが終了すれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
nodejs, rust
領域
devtools
issue の種類
バグ
難易度
5/5
見積もり時間
1週間以上
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
32/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。