プロンプトとコンテキスト
リアルタイムコラボレーションアプリは、ドロップされる可能性のあるカーソル位置やハートビートを送信しながら、ドキュメント操作を確実に配信する必要があります。チームはWebTransportを選択しましたが、クローズ時の動作、ネットワーク変更、再接続、バックプレッシャー、クリーンアップを定義していません。ライフサイクルを設計し、信頼性のあるストリーム、信頼性のないデータグラム、およびHTTP/3接続の境界を説明してください。
W3C WebTransport APIは信頼性のあるストリームと信頼性のないデータグラムを公開し、RFC 9297はHTTPデータグラムを定義しています。優れた回答は、アプリケーションセッションをトランスポートから分離し、close()をすべてのビジネスメッセージが配信された証拠として扱いません。
面接官がテストしていること
- セッションクローズ、ストリームクローズ、データグラム損失、およびネットワーク障害の区別。
- 再接続、セッション復旧、シーケンス番号、冪等性、およびスナップショットの設計。
- ストリームのバックプレッシャー、データグラムの制限、遅いクライアント、およびリソース上限の処理。
- クローズコード、理由、タイムアウト、およびオブザーバビリティの定義。
- ブラウザ、プロキシ、HTTP/3、およびフォールバックの明確な境界の設定。
明確化のための質問
- どのメッセージが信頼性と順序性を必須とし、どのメッセージが破棄可能または最新値への縮小が可能ですか?
- ネットワーク変更をまたいでセッションを復旧できますか?許容される復旧時間と操作履歴はどのくらいですか?
- ユーザーごとの同時セッション数、ストリーム数、データグラムレートにはどのような制限が適用されますか?
- クローズはユーザー起点、メンテナンス、認証切れ、過負荷、またはプロトコルエラーのいずれですか?
- ブラウザとプロキシはHTTP/3経由のWebTransportをサポートしていますか?また、明示的なフォールバックは何ですか?
30秒の回答
アプリケーションセッションIDを単一のWebTransport接続から分離します。信頼性のある操作はシーケンス番号と冪等性キーを付与してストリーム経由で送信し、カーソルやハートビートは損失を許容するデータグラムとして送信します。障害発生時はサーバー側のセッション状態を短時間保持し、指数バックオフと最後に確認されたシーケンスを使用して再接続し、スナップショットと差分から復旧します。グレースフルクローズでは、新規作業を停止し、信頼性のあるストリームをドレイン(排出し切る)し、アプリケーション完了マーカーを送信し、コードを指定してクローズし、ハードタイムアウトを強制します。すべてのバッファとリソースに上限を設けます。
詳細な回答
1. アプリケーションおよびトランスポートセッションの確立
アプリケーションセッションIDはコラボレーションルームにおけるユーザーの論理的なメンバーシップを表し、WebTransportインスタンスは単一のネットワーク接続です。ハンドシェイク後、オリジン、認証、テナント、およびルーム権限を検証し、接続IDを作成してアプリケーションセッションにマッピングします。再接続時は新しい接続IDが作成され、他のユーザーのセッションが付与されることは決してありません。
最後に確認された操作シーケンス、スナップショットバージョン、サブスクリプション、および有効期限を保存します。切断後は、リソースを解放する前に短いTTLの間、アプリケーション状態を中断(suspended)としてマークします。
2. メッセージごとのストリームまたはデータグラムの選択
ドキュメント操作、権限変更、および確認応答(ack)には、明示的なフレーミング、バージョン、シーケンス番号、および冪等性キーを持つ信頼性のあるストリームを使用します。カーソル、ライブメトリクス、およびハートビートにはデータグラムを使用し、受信側は古いタイムスタンプやバージョンを破棄します。配信必須のビジネスイベントをデータグラムに含めてはなりません。
データグラムは配信、順序付け、または再送の保証を提供せず、パスおよび実装によるサイズ制限があります。損失とレイテンシを測定し、頻度を減らすか、最新の状態のみを送信します。信頼性のあるストリームでは、無制限のメモリキューの代わりにWritableStreamのバックプレッシャーを使用します。
3. バックプレッシャーと遅いクライアントの処理
信頼性のあるストリームごとに、送信ウィンドウ、未確認ackの制限、および最大フレームサイズを設定します。書き込みが保留状態のままになる場合はプロデューサーを一時停止し、タイムアウト時には切断するか非クリティカルなサブスクリプションを縮小します。データグラムにはトークンバケットとセッションごとのバジェットを使用します。古いカーソルをドロップする方が、ドキュメント操作をブロックするよりも望ましいです。
また、セッション数、ストリーム数、同時デコード数、および総メモリ量に上限を設けます。単一の遅いクライアントがイベントループを消費し尽くさないよう、メトリクスをテナントごとに集約します。
4. 切断と復旧の設計
クライアントは信頼性のある操作にローカルシーケンス番号と冪等性キーを割り当て、確認応答後にチェックポイントを進めます。再接続ハンドシェイクには、セッションID、最後に確認されたシーケンス、およびケーパビリティが含まれます。サーバーはセッションの所有権を検証し、スナップショット、差分、または回復不能エラーを返します。
古い接続と新しい接続が同時に送信できないよう、復旧中は新しい副作用を一時停止します。エポック(epoch)を使用して古い接続からの書き込みを無効化し、復旧が完了した後にのみプロデューサーを再開します。
5. グレースフルシャットダウンの設計
メンテナンス中は、ドレイン状態をブロードキャストし、新規セッションを拒否し、非クリティカルなデータグラムを停止します。信頼性のあるストリームに現在のフレームを完了させてアプリケーション完了マーカーを送信させ、制限された待機時間の後にセッションをクローズします。ブラウザのclose()はセッションの終了とクローズ情報を伝達しますが、ビジネス上の確認応答ではありません。
クローズコードを正常終了、認証切れ、過負荷、プロトコルエラー、およびメンテナンスに分類します。理由は短く非機密情報にとどめます。ハードタイムアウトに達したら直ちにリソースを解放し、未完了の操作を記録します。
6. 認証の再チェックとネットワーク変更
新規または復旧された各接続は、認証情報、オリジン、テナント、およびルーム権限を再検証します。セッションIDのみに基づいて復旧してはなりません。ネットワークの変更によりアドレスが変わる場合があります。アプリケーションの復旧には新しい接続が使用され、エポックによって古いパスからの書き込みが防止されます。
WebTransportまたはHTTP/3が利用できない場合は、明示的にフォールバックをネゴシエーションし、信頼性、レイテンシ、およびセキュリティの違いを再定義します。データグラムにWebSocketのクローズセマンティクスを適用してはなりません。
7. 障害モードのオブザーバビリティとテスト
接続の作成、ハンドシェイクの失敗、クローズコードと理由、ストリームのバックプレッシャー、ドロップされたデータグラム、再接続回数、復旧時間、および未確認の操作を記録します。トークンや機密性の高いドキュメントコンテンツをログに記録してはなりません。メトリクスはクライアント、ネットワークタイプ、テナントごとにセグメント化します。
メンテナンス、モバイルネットワークの変更、HTTP/3プロキシのブロック、遅いクライアント、データグラムのバースト、および重複した再接続をテストします。受け入れ基準には、重複した副作用がないこと、明示的な復旧制限、期限切れセッションのクリーンアップ、および制限されたクローズレイテンシが含まれます。
模範回答
私ならアプリケーションセッションをWebTransport接続から分離します。信頼性のあるドキュメント操作にはシーケンス番号と冪等性キーを持つストリームを使用し、カーソルとハートビートには損失を許容するデータグラムを使用します。クライアントはチェックポイントを保存し、セッションIDと最後に確認されたシーケンスを使用して再接続します。サーバーはユーザーとテナントを検証し、スナップショットと差分から復元し、エポックを使用して古い書き込みを無効化します。
グレースフルシャットダウンではドレイン状態に入り、新しいメッセージと非クリティカルなデータグラムを停止し、信頼性のあるストリームを排出し、アプリケーション完了マーカーを送信してから、コードとハードタイムアウトを指定してクローズします。セッション、ストリーム、バッファ、および再接続に上限を設け、損失、バックプレッシャー、クローズ理由、および復旧時間を監視します。フォールバックはすべて明示的にネゴシエーションします。
よくある間違い
- データグラムを信頼性のあるメッセージとして扱ったり、
close()をビジネス確認応答として扱ったりすること。 - チェックポイント、エポック、または冪等性キーなしで障害後に新しい接続を作成すること。
- 遅いクライアントのデータを無期限にバッファリングし、メモリやイベントループを枯渇させること。
- ユーザー、テナント、オリジン、および権限を再検証せずにセッションIDのみで復旧すること。
- クローズ時にドレイン処理、ハードタイムアウト、または未完了操作の監査を省略すること。
- HTTP/3のブロック、ブラウザのサポート状況、およびプロキシの動作を無視すること。
- 完全なトークン、ドキュメントのコンテンツ、または機密性の高いクローズ理由をログに記録すること。
フォローアップの質問と回答
データグラムには何を含めるべきですか?
カーソル、一時的な姿勢(pose)、高頻度のハートビートなど、損失を許容できる短命な値です。到達が必須のビジネス操作には信頼性のあるストリームを使用します。
再接続後の操作の重複をどのように防ぎますか?
冪等性キーとシーケンス番号を割り当て、サーバー側でセッションとエポックごとに重複を排除し、確認応答を受け取った後にのみチェックポイントを進めます。
メンテナンスによるシャットダウンはどのように機能すべきですか?
新規セッションを停止してドレイン状態をブロードキャストし、非クリティカルなデータグラムを停止し、信頼性のあるストリームを排出し、完了マーカーを送信してから正常にクローズします。ハードタイムアウト時には強制的にクリーンアップを実行します。
セッションTTLが切れるとどうなりますか?
回復不能エラーを返し、再認証と再参加を要求します。古いセッションIDによって権限が延長されてはなりません。
データグラムが大きすぎる場合や損失率が高い場合はどうしますか?
サイズとレートを制限し、状態を圧縮または合算(coalesce)し、最新の値のみを保持します。ビジネスイベントが信頼性のないデータグラムに依存することはできません。
フォールバックがセマンティクスを維持していることをどのように証明しますか?
プロトコルごとに信頼性、順序付け、復旧、および認証の違いを文書化します。重複した副作用を測定しながら、切断、プロキシのブロック、遅いクライアント、および重複した再接続をテストします。