GitHub Actions
Deploy from GitHub Actions [dev] - 2025-10-31 07:28:50
68f7925
# 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)