active: true
derived: false
groups:
- LIMIT
header: |
  TokenBucket (GCRA)
level: 2.18
links:
- ARCH008: 3P_GwS0JFM40QovY318yJfHonSHWqQiSUXfnIrPXI7w=
normative: true
ref: ''
reviewed: Rk1IozVD5Sbu6p9PQuXqfsh55lfSlYxKi-gO57G36TQ=
text: |
  ## インターフェース

  ```python
  class TokenBucket(LimiterProtocol):
      def consume(self, cost: float = 1.0) -> None: ...
      async def consume_async(self, cost: float = 1.0) -> None: ...
  ```

  ## 振る舞い

  ### GCRAアルゴリズム
  - 各リクエストに対して「次回実行可能な理論時刻 (TAT: Theoretical Arrival Time)」を計算・更新する。
  - 現在時刻が `TAT - 許容バースト` 以前の場合、リクエストを拒否または待機させる。

  ### 同期 vs 非同期
  - `consume`: 待機が必要な場合は `time.sleep()` でブロック。
  - `consume_async`: 待機が必要な場合は `asyncio.sleep()` で非占有待機。

  ## パラメータ詳細

  | 設定 | デフォルト | 説明 |
  |---|---|---|
  | `tokens_per_minute` | 必須 | 1分間に許可する平均リクエスト数（コスト合計） |
  | `max_burst` | `1.0` | 許容されるバースト数（トークン単位） |

  ## エラーハンドリング

  - **即時拒否モード**: 待機を許容しない設定でレート超過した場合、`RateLimitError` (ValueErrorのサブクラス) を送出する。

  ## エッジケース

  - **高コストリクエスト**: `max_burst` を超えるコストを持つ単一リクエストは、常に拒否される。
  - **アイドル時間**: 長時間リクエストがない場合も、`TAT` は現在時刻より過去に一定以上離れないよう補正される（過度なバーストの防止）。
