# Gradio API接続プール設計書 ## 1. 概要 ### 1.1 背景 現在のシステムではAPI呼び出しのたびに新規接続を確立しており、以下の問題が発生している: - 接続確立のオーバーヘッド(2-5秒/リクエスト) - HuggingFace Spacesへの不要な負荷 - ユーザー体験の劣化 - 長時間実行API(5-10分)への対応不足 ### 1.2 目的 - API応答時間の大幅な短縮(2-5秒 → 200-500ms) - 接続の再利用による効率化 - ユーザーごとの接続先固定による体験の一貫性 - 長時間実行APIへの対応(最大50並列接続) ## 2. アーキテクチャ ### 2.1 システム構成図 ``` ┌─────────────────────────────────────┐ │ Next.js Application (HF Space) │ ├─────────────────────────────────────┤ │ GradioConnectionPool │ │ (シングルトンインスタンス) │ │ ┌────────────────────────────┐ │ │ │ 接続プール (遅延初期化) │ │ │ │ ・Repository A (1-50接続) │ │ │ │ ・Repository B (1-50接続) │ │ │ │ ・Repository C (1-50接続) │ │ │ └────────────────────────────┘ │ │ ┌────────────────────────────┐ │ │ │ 接続キュー管理 │ │ │ │ ・リポジトリ別キュー │ │ │ │ ・タイムアウト処理 │ │ │ └────────────────────────────┘ │ │ ┌────────────────────────────┐ │ │ │ ユーザー割り当てMap │ │ │ │ email → repository │ │ │ │ (TTL: 1時間) │ │ │ └────────────────────────────┘ │ └─────────────────────────────────────┘ ↓ WebSocket/HTTP永続接続 ┌─────────────────────────────────────┐ │ Gradio Spaces (HuggingFace) │ │ ・dentsudigital/mugenAILP_1 │ │ ・dentsudigital/mugenAILP_dev │ │ ・dentsudigital/mugenAILP_stage │ └─────────────────────────────────────┘ ``` ### 2.2 コンポーネント関係図 ```mermaid graph TD A[API Handler] --> B[getGradioClient] B --> C[ConnectionPool Singleton] C --> D[Connection Manager] C --> E[Queue Manager] C --> F[Health Monitor] C --> G[User Assignment Manager] D --> H[Repository A Pool
1-50 connections] D --> I[Repository B Pool
1-50 connections] D --> J[Repository C Pool
1-50 connections] E --> K[Request Queue] F --> L[Health Check Timer
5分間隔, 最大5接続チェック] ``` ## 3. 設計原則 ### 3.1 遅延初期化(Lazy Initialization) - **原則**: 接続は必要になるまで作成しない - **理由**: 起動時間の短縮とリソースの効率的利用 - **実装**: 初回リクエスト時に最小接続数(5)を作成、その後オンデマンドで追加 ### 3.2 接続プールの動的管理 - **最小接続数**: リポジトリあたり5接続 - **最大接続数**: リポジトリあたり50接続 - **スケーリング**: 需要に応じて自動的に接続を追加 - **クリーンアップ**: 10分間アイドル状態の接続を自動削除 ### 3.3 負荷分散 - **新規ユーザー**: ラウンドロビン方式で均等に分配 - **既存ユーザー**: 同一リポジトリに固定(セッション一貫性) - **匿名ユーザー**: 最も負荷が低いリポジトリを選択 ### 3.4 キュー管理 - **接続待ち**: 全接続が使用中の場合はキューで管理 - **タイムアウト**: 30秒で待機タイムアウト - **優先度**: FIFO(先入れ先出し)方式 ### 3.5 フォールトトレランス - **ヘルスチェック**: 5分間隔で最大5接続をチェック - **自動再接続**: 切断検出時に自動的に再接続 - **フェイルオーバー**: 接続失敗時は別リポジトリへ切り替え ## 4. 詳細設計 ### 4.1 クラス設計 #### 主要コンポーネント - **GradioConnectionPool**: シングルトンパターンで実装される接続プール管理クラス - **接続プール**: リポジトリごとに複数の接続を保持(5-50接続/リポジトリ) - **ユーザー割り当て管理**: メールアドレスとリポジトリのマッピング(TTL: 1時間) - **キュー管理**: 接続待機リクエストの管理(タイムアウト: 30秒) - **ヘルスモニター**: 定期的な接続状態確認(5分間隔) #### 主要パラメータ | パラメータ | 値 | 説明 | |-----------|-----|------| | 最小接続数 | 5 | リポジトリあたりの初期接続数 | | 最大接続数 | 50 | リポジトリあたりの上限 | | アイドルタイムアウト | 10分 | 未使用接続の削除基準 | | キュータイムアウト | 30秒 | 接続待機の上限時間 | | ヘルスチェック間隔 | 5分 | 接続確認の実行間隔 | | ユーザー割り当てTTL | 1時間 | 割り当て情報の保持期間 | ### 4.2 リポジトリ選択戦略 - **匿名ユーザー**: 最小負荷のリポジトリを自動選択 - **登録ユーザー**: 初回はラウンドロビン、以降は同一リポジトリに固定 - **負荷分散**: 使用中接続数が最も少ないリポジトリを優先 ### 4.3 エラーハンドリング ``` エラー種別と対応: ├─ 接続タイムアウト │ └─ 3回リトライ後、次のリポジトリへ ├─ Space metadata エラー │ └─ 即座に次のリポジトリへ ├─ 接続切断 │ └─ 自動再接続を試行 └─ 全リポジトリ接続失敗 └─ エラーを上位に伝播 ``` ## 5. データフロー ### 5.1 通常のAPI呼び出しフロー ``` 1. APIハンドラーがgetGradioClient(email)を呼び出し 2. ConnectionPoolシングルトンを取得 3. 初期化確認(未初期化なら遅延初期化を実行) 4. ユーザーのメールアドレスから適切なリポジトリを選択 5. 利用可能な接続を探す a. 未使用の接続があれば即座に返却 b. 全て使用中で容量に余裕があれば新規接続作成 c. 容量上限に達していればキューに追加して待機 6. client.predict()でAPIを実行 7. 接続を解放(isInUse = false) 8. キューがあれば次の待機リクエストを処理 ``` ### 5.2 遅延初期化フロー ``` 1. 初回のgetClient()呼び出し 2. initialize()が自動実行される 3. 各リポジトリに最小接続数(5)を並列作成 4. 成功した接続をプールに登録 5. ヘルスチェックタイマーを開始 6. 初期化完了 ``` ### 5.3 キュー処理フロー ``` 1. 全接続が使用中でgetClient()が呼ばれる 2. addToQueue()でキューに追加 3. 30秒のタイムアウトタイマーを設定 4. 他の接続が解放されるのを待機 5. 接続が解放されたらprocessQueue()実行 6. キューから取り出してクライアントを提供 7. タイムアウトした場合はエラーで拒否 ``` ## 6. パフォーマンス目標 ### 6.1 改善目標 - 接続確立オーバーヘッドの削減(2回目以降のリクエスト) - 長時間実行APIのサポート(複数並列接続による) - リソース使用量の管理(接続数上限設定) ### 6.2 計測ポイント - 接続確立時間 - API応答時間 - キュー待機時間 - プール使用率 - エラー率 ## 7. 監視と可観測性 ### 7.1 統計情報エンドポイント ``` GET /api/admin/pool-stats Response: { "pools": { "mugenAILP_1": { "totalConnections": 15, "availableConnections": 12, "inUseConnections": 3, "queueLength": 0, "healthyConnections": 15, "unhealthyConnections": 0 }, "mugenAILP_dev": { "totalConnections": 8, "availableConnections": 8, "inUseConnections": 0, "queueLength": 0, "healthyConnections": 8, "unhealthyConnections": 0 }, "mugenAILP_stage": { "totalConnections": 5, "availableConnections": 4, "inUseConnections": 1, "queueLength": 0, "healthyConnections": 5, "unhealthyConnections": 0 } }, "totalConnections": 28, "availableConnections": 24, "inUseConnections": 4, "totalQueued": 0, "userAssignments": 15, "initialized": true, "healthCheckRunning": false, "lastHealthCheck": "2024-01-20T10:30:00Z" } ``` ### 7.2 ログ出力項目 - プール初期化状態 - 接続の作成/削除 - ユーザー割り当て - キュー状態変更 - ヘルスチェック結果 - エラーとタイムアウト ## 8. メモリ管理 ### 8.1 リソース管理戦略 - **ユーザー割り当て**: TTL 1時間で自動削除 - **接続プール**: - 最小5接続を維持 - 最大50接続まで拡張可能 - 10分間アイドルで自動削除(最小接続数まで) - **キュー管理**: 30秒でタイムアウト - **ヘルスチェック**: 5分間隔で最大5接続をチェック ### 8.2 接続の破棄条件 1. アイドル時間が10分を超過 2. ヘルスチェック失敗(3回連続) 3. 手動クリーンアップの実行 4. プロセス終了時 ### 8.3 メモリ使用量 - 接続プール: リポジトリ数 × 接続数に依存 - ユーザー割り当て: アクティブユーザー数に依存 - キュー: 待機リクエスト数に依存 ## 9. セキュリティ考慮事項 ### 9.1 認証情報の保護 - Gradio TokenはプロセスメモリにのみFsaved保持 - 環境変数から読み込み、ログには出力しない ### 9.2 ユーザー情報の扱い - メールアドレスはマッピング用途のみ - 統計情報にはハッシュ化して記録 ### 9.3 シングルトンパターンのセキュリティ - グローバル変数でインスタンスを保護 - 外部からの直接アクセスを防止 - getConnectionPool()関数経由でのみアクセス可能 ## 10. 制約事項 ### 10.1 HuggingFace Spaces環境 - デプロイ先: HuggingFace Spaces - Dockerコンテナとして実行 ### 10.2 制限事項 - 接続プールはメモリ上に保持 - プロセス再起動時に接続はリセット - 単一プロセスでの実行 ## 11. 実装状況 ### 完了済み機能 - [x] ConnectionPoolクラスの実装(シングルトン) - [x] 遅延初期化の実装 - [x] オンデマンド接続作成(最大50接続/リポジトリ) - [x] キュー管理システム(30秒タイムアウト) - [x] ヘルスチェック機能(5分間隔、最大5接続チェック) - [x] 接続クリーンアップ(10分アイドルタイムアウト) - [x] ユーザー割り当て管理(1時間TTL) - [x] 統計情報API(/api/admin/pool-stats) - [x] エラーハンドリングとフォールバック - [x] 詳細なロギング ### 実装の特徴 - **シングルトンパターン**: アプリケーション全体で単一インスタンス - **遅延初期化**: 初回リクエスト時に接続作成 - **動的スケーリング**: 5-50接続の範囲で自動調整 - **長時間API対応**: 5-10分のAPI実行に対応 - **効率的なヘルスチェック**: 全接続ではなく5接続のみチェック ## 12. 今後の拡張可能性 ### 12.1 短期的改善 - プリエンプティブな再接続(接続が切れる前に再接続) - 優先度付きキューの実装 - 接続プールのウォームアップ機能 - メトリクスの詳細化とダッシュボード ### 12.2 長期的展望 - Redisを使った分散キャッシュ - 複数インスタンス間での接続共有 - WebSocket接続の最適化 - 自動スケーリングポリシーの実装 - 予測的な接続作成(使用パターン学習) ## 13. 参考資料 - [Gradio Client Documentation](https://www.gradio.app/docs/client) - [HuggingFace Spaces Documentation](https://huggingface.co/docs/hub/spaces) - [Next.js on HuggingFace Spaces](https://huggingface.co/docs/hub/spaces-sdks-docker-nextjs)