ホームへ戻る

GitHub Repo

Difyコミュニティ、Node.js SDKのストリーミングタイムアウトが無効になる問題を報告

10月31日のDifyコミュニティの報告によると、Node.js SDKのタイムアウト設定がストリーミング応答の後続読み取りに適用されない可能性がある。投稿者は切り分けた再現例を示したが、本番環境への影響は確認されておらず、ストリーミングのタイムアウト契約も明確になっていない。

The original uploader was Ggia at Greek Wikipedia. · CC BY-SA 2.5 · Image source
zh-Hant

DifyのNode.js SDKで、ストリームのライフサイクルに関する信頼性の問題が報告された。10月31日に公開されたissueによると、dify-client 3.1.0はストリームオブジェクトを返した後、タイムアウト保護を早期に解除する可能性がある。レスポンスヘッダーが届いても本文の送信が止まった場合、後続の読み取りが設定期限を超えて待ち続けるおそれがある。この報告は特定のソースコードバージョンを対象としたもので、本番環境での障害報告ではない。issueと再現コード

投稿者の分析によると、requestRaw()はAbortControllerで動作するタイマーを作成するが、finallyブロックで常にタイマーを解除する。通常のJSON経路では本文のデコードを待ってから処理する一方、ストリーミング経路では読み取り可能なストリームを早期に返すため、データの消費が終わる前にクリーンアップが実行される。その結果、同じtimeout設定でも、レスポンス形式によって実際に適用される範囲が異なる。報告に記載されたコード経路の説明

投稿者はfetchをメモリ上のResponseに置き換え、本文が開いたままになる状況を再現した。タイムアウトを20ミリ秒に設定し、リトライを無効にすると、JSONの対照ケースではTimeoutErrorが発生した一方、SSEとバイナリの読み取りは120ミリ秒の観察期間が終わっても完了しなかった。このテストはタイマー管理の問題を切り分けたもので、Difyのサーバーやモデルには接続していない。そのため、実際のネットワーク環境での停止時間や発生率を推定することはできない。テスト条件と制約

エンジニアリングチームは、レスポンスの取得、本文の読み取り完了、キャンセルシグナルの発火という各時点を区別する必要がある。Node.jsの公式ドキュメントによると、AbortControllerはキャンセルシグナルを発行するために使われ、AbortSignal.timeout()は指定時間の経過後にシグナルを発火させる。ただし、アプリケーション側でも、実際の読み取り経路がそのシグナルを受け取り、処理する必要がある。Node.jsドキュメント

確認時点ではissueは未解決のままで、正式な修正状況も確認されていない。今後の焦点は、メンテナーがストリームの期限をどう定義するかにある。応答全体を対象にするのか、それともデータの進展がない状態に対するアイドルタイムアウトを別途設けるのか、という点だ。この問題から考えると、回帰テストでは正常終了、読み取りエラー、明示的な破棄も対象とし、エラーが消費側まで伝わることを確認する必要がある。タイマーを延長するだけでは、クリーンアップやエラー伝播に不備が残る可能性がある。

出典

  1. Node.js SDK timeout stops applying after a streaming response is returned · Issue #45198
  2. Node.js Global objects — AbortController and AbortSignal