# limiter

`beautyspot.limiter` モジュールは、外部サービスへの過度なアクセスを制御し、実行の安定性を担保するためのレートリミッターを提供します。

::: beautyspot.limiter

## プロトコル定義

`beautyspot` は、レートリミットの具体的なアルゴリズムを抽象化するため、以下のプロトコルを定義しています。

### LimiterProtocol

リミッターが実装すべき標準インターフェースです。

* `consume(cost: int) -> None`: 指定したコスト分のトークンを消費します。不足している場合は、利用可能になるまで現在のスレッドをブロックします。
* `consume_async(cost: int) -> None`: `consume` の非同期版です。非ブロッキングで待機します。

## TokenBucket クラス

GCRA (Generic Cell Rate Algorithm) に基づいた、滑らかなレート制限を実現する実装です。

### 技術的特徴

* **厳格なペース調整 (Strict Pacing)**:
長期間アイドル状態だった後にリクエストが集中しても、バースト（一気読み）を発生させず、設定されたレートに従って均等に処理を分散させます。
* **ハイブリッド対応**:
内部で `threading.Lock` を使用しており、マルチスレッド環境と `asyncio` 環境の両方で安全に使用できます。
* **モノトニッククロックの採用**:
時刻の計算には `time.monotonic()` を使用しているため、システムの時刻変更やうるう秒の影響を受けず、正確なインターバル計算が可能です。
* **フェイルファスト設計**:
1つのタスクのコストが、設定された「1分あたりの最大トークン数 (TPM)」を超える場合、決して完了できないリクエストとして即座に `ValueError` を送出します。

### 基本設定

| 引数 | 型 | 説明 |
| --- | --- | --- |
| `tokens_per_minute` | `int` | 1分間に許容される合計コスト（TPM）。 |

## 内部アルゴリズム: GCRA

`TokenBucket` は、内部的に **Theoretical Arrival Time (TAT)** という概念を使用して、次のリクエストが許可される最短時刻を管理しています。

1. リクエストが発生すると、現在の時刻と TAT を比較します。
2. `現在時刻 < TAT` の場合、その差分だけ待機（sleep）が必要と判断されます。
3. リクエストのコストに応じて TAT を将来へと更新し、予約（Reservation）を行います。

## 例外

* **ValueError**:
* `tokens_per_minute` に 0 以下の値を指定した場合。
* `consume` に渡された `cost` が、リミッターの最大容量（1分間の制限値）を超えている場合。

