Skip to content

fix(room): a lagging participant goes permanently deaf #42

Description

@smileygames

観測

配送ポンプが broadcast の lag で終了し、以後その参加者へ何も届かなくなる。ソケットは開いたままなので、画面にも名簿にも異常が出ない。

serve_participant の pump は次の形をしている(src-tauri/src/room.rs)。

while let Ok(fanout) = from_room.recv().await {
    if fanout.origin == own_origin { continue; }
    if sink.send(Message::Text(fanout.frame.into())).await.is_err() { break; }
}

tokio::sync::broadcast::Receiver::recv は、受信が容量(256)ぶん遅れたとき Err(RecvError::Lagged(n)) を返す。while let Ok(..) はこれで抜ける。Lagged の後も receiver 自体は使えるため、本来は取りこぼした件数を記録して継続できる。現状は恒久的に離脱する。

Err(RecvError::Closed) との区別も無い。

前提

  • feat(room): one post frame, so a participant is a participant #39 以前から同じ形であり、今回の投稿モデル統一で入ったものではない。ただし feat(room): one post frame, so a participant is a participant #39 で全参加者への fan-out が本格的に動き出すため、露出する確率は上がる。
  • 発生条件は、ある参加者の送信が 256 件ぶん滞留すること。エージェントの応答が詰まる、ソケットの書き込みが遅い、といった状況で起こりうる。
  • 掲示板として常時複数の参加者が座る前提では、片方が黙ったまま生きているように見える状態は診断が難しい。

制約

  • LaggedClosed を分けて扱う。Lagged は継続、Closed は離脱。
  • 取りこぼしは沈黙させない。件数を stderr へ出す。部屋の発言が落ちたことは参加者側から観測できないため、ログが唯一の手がかりになる。
  • 落ちた発言の再送は行わない。部屋は履歴を持たない設計であり、ここで持たせない。

対象ファイル

  • src-tauri/src/room.rs

完了条件

  • lag した参加者が、その後の発言を受け取り続ける。
  • 取りこぼした件数が stderr に出る。
  • ソケットが閉じたときは従来どおり離脱し、名簿から外れる。

関連

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug動いていない、壊れているforming本文を再構築しながら要求を整えている状態

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions