partyserver: with hibernation off, a client close without a status code (1005) is never answered, so the client stays in CLOSING

オープン 初心者向け
#429 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
69/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
typescript
領域
networking

調査の方向性

まず closeQuietly の実装と #394 の変更を読みます。issue では予約済みの close code が特定され、hibernate: false を使った再現手順が示されています。コードなしの close を再現し、6 秒後のソケット状態を確認します。その後、修正後にクライアントが Close フレームを受信し、CLOSING から抜けることを確認します。

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

説明

Since #394, closeQuietly skips the reply for the reserved codes 1005, 1006 and 1015. 1006 and 1015 mean that no Close frame arrived. 1005 does not: it is what the server reports when the client sent a real Close frame with an empty body, which is what ws.close() with no arguments does. The transport is still open, and the client waits in CLOSING for the server's Close frame.

On a non-hibernating server (static options = { hibernate: false }) that frame never comes. y-partyserver's provider calls ws.close() with no code in disconnect(), so every YProvider.disconnect() ends this way. The provider keeps wsconnected === true until the socket finally dies, and a connect() in the meantime does nothing.

The #394 notes say compatibility dates on or after 2026-04-07 auto-reply to Close frames. That does not happen for these sockets: the result below is on compatibility date 2026-11-01.

Repro (wrangler 4.159.0, workerd 1.20261109.1, partyserver 0.5.10, y-partyserver 2.2.0, compatibility date 2026-11-01, hibernate: false):

  1. Start a YServer subclass with hibernate: false (for example via unstable_startWorker).
  2. Open a raw WebSocket to /parties/<party>/<room>, wait for open, then call ws.close() with no code.
  3. With the stock onClose, the client is still in readyState 2 (CLOSING) after 6000 ms.
  4. Add if (code === 1005) connection.close(1000, 'Closed') to onClose. The close completes in 14 ms and the client sees 1000.

In our production Worker that reply has run on every pause, reload and tab close since 2026-11-09. wrangler tail during a test run (57 events) showed no exceptions and no Network connection lost rejections.

Suggested fix: in closeQuietly, skip the reply only for 1006 and 1015. For 1005, reply with ws.close() (no code) or with 1000. A peer that sent a code-less Close frame is still there to receive the answer.

主要言語
TypeScript
スター
1.3k
フォーク
84
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

cloudflare/partykit のほかの issue

cloudflare/partykit の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

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

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