-- Views
December 23, 25
スライド概要
F#で非同期ストリームを扱った話
F# でちょっとずつ返す
ちょっとずつ返す?
ちょっとずつ返す? Request Request DAG API (F# Minimal API) Streaming Response LLM (Gemini) Streaming Response
ちょっとずつ返す? SCAI API DAG API (F# Minimal API) LLM (Gemini)
選択肢 1. Server-Sent Events ( SSE ) 2. IAsyncEnumerable<T> の活用 a. 非同期ストリームを表現するための .NET の標準的なインターフェース
Server-Sent Events ● サーバーからクライアントへ一方向にデータを逐次PushするW3C標準の通信方式 MDN: https://developer.mozilla.org/ja/docs/Web/API/Server-sent_events
IAsyncEnumerable<T> ● 非同期ストリームを表現するための .NET の標準的なインターフェース ● Chunked transfer encoding (HTTP/1.1で導入されたデータ転送方式)を使用 ○ チャンク形式のHTTPリクエスト ○ レスポンスヘッダー:Transfer-Encoding: chanked .NET: https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.generic.iasyncenumerable-1?view=net-9.0
DAG API では? ● IAsyncEnumerable<T> TaskSeq を使った実装 ○ ● 理由 ○ .NET 標準機能で実装可能 ■ ○ SSE は .NET 8 だと標準サポートがない ブラウザ向けではない ■ だいたいのプログラミング言語、HTTPクライアントライブラリで標準的にサ ポートされている
ポイント DAG API ③ Entry Point ② ① Driver
ポイント 1. Driver で逐次データを受け取る 2. Driver から アプリケーション構成レイヤーまで逐次データを返す 3. HTTP レスポンスとしてクライアントへ逐次データを返す
実装例
ハマった箇所 ● do! Task.Yield() や Task.Delay() を入れないと逐次データが返ってこない ○ まとめて返ってくる
図解 HTTPフレームワーク (ASP.NET Core) TaskSeq(F#) MoveNextAsync() を呼ぶ 要素を受け取る 要素を生成 (yield line) 制御をHTTPフレームワークに戻す 明示的な非同期一時停止 (do! Task.Yield()) HTTPレスポンスに逐次書き出し(フラッシュ)
解説 ● フラッシュされるタイミングは、HTTPフレームワークが管理している ● 制御を明示的に戻す必要がある ○ Task.Yield(), Task.Delay()
おわり