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 コンポーネント関係図

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. 実装状況

完了済み機能

  • ConnectionPoolクラスの実装(シングルトン)
  • 遅延初期化の実装
  • オンデマンド接続作成(最大50接続/リポジトリ)
  • キュー管理システム(30秒タイムアウト)
  • ヘルスチェック機能(5分間隔、最大5接続チェック)
  • 接続クリーンアップ(10分アイドルタイムアウト)
  • ユーザー割り当て管理(1時間TTL)
  • 統計情報API(/api/admin/pool-stats)
  • エラーハンドリングとフォールバック
  • 詳細なロギング

実装の特徴

  • シングルトンパターン: アプリケーション全体で単一インスタンス
  • 遅延初期化: 初回リクエスト時に接続作成
  • 動的スケーリング: 5-50接続の範囲で自動調整
  • 長時間API対応: 5-10分のAPI実行に対応
  • 効率的なヘルスチェック: 全接続ではなく5接続のみチェック

12. 今後の拡張可能性

12.1 短期的改善

  • プリエンプティブな再接続(接続が切れる前に再接続)
  • 優先度付きキューの実装
  • 接続プールのウォームアップ機能
  • メトリクスの詳細化とダッシュボード

12.2 長期的展望

  • Redisを使った分散キャッシュ
  • 複数インスタンス間での接続共有
  • WebSocket接続の最適化
  • 自動スケーリングポリシーの実装
  • 予測的な接続作成(使用パターン学習)

13. 参考資料