Spaces:
Sleeping
Sleeping
| # 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<br/>1-50 connections] | |
| D --> I[Repository B Pool<br/>1-50 connections] | |
| D --> J[Repository C Pool<br/>1-50 connections] | |
| E --> K[Request Queue] | |
| F --> L[Health Check Timer<br/>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) |