
# Ograniczanie liczby żądań

Queuety obsługuje ograniczanie liczby żądań dla poszczególnych modułów obsługi, aby zapobiegać przeciążeniu zewnętrznych interfejsów API lub innych ograniczonych zasobów. Po osiągnięciu limitu przez moduł obsługi procesy robocze pozostawiają jego zadania w oczekiwaniu i pobierają je ponownie, gdy w oknie zwolni się miejsce.

## Ustawianie limitu liczby żądań

Zastosuj limit liczby żądań podczas przekazywania zadania:

```php
use Queuety\Queuety;

Queuety::dispatch( 'call_openai', $payload )
    ->rate_limit( 10, 60 ); // max 10 executions per 60 seconds
```

Dwa argumenty to:
1. `$max` – maksymalna liczba wykonań dozwolona w oknie
2. `$window` – czas trwania okna w sekundach

Limit ustawiony podczas przekazywania zadania jest rejestrowany tylko w procesie PHP, który je przekazuje. Proces roboczy działający w osobnym procesie, taki jak `wp queuety work`, nie widzi tego limitu. Limity, które mają obowiązywać we wszystkich procesach, ustaw w metodzie `config()` modułu obsługi, jak pokazano poniżej ([#3](https://github.com/inline0/queuety/issues/3)).

## Limity liczby żądań na poziomie modułu obsługi

Ustaw limity liczby żądań w metodzie `config()` modułu obsługi, aby obowiązywały przy każdym przekazaniu zadania:

```php
use Queuety\Handler;

class CallOpenAIHandler implements Handler {
    public function handle( array $payload ): void {
        // Call the API...
    }

    public function config(): array {
        return [
            'rate_limit' => [ 60, 60 ], // 60 requests per minute
        ];
    }
}
```

## Jak to działa

Limity liczby żądań są śledzone według nazwy modułu obsługi. Po pobraniu zadania proces roboczy rejestruje limit modułu obsługi (z jego `config()`) i sprawdza ogranicznik liczby żądań. Jeśli moduł obsługi osiągnął limit, proces roboczy natychmiast odkłada zadanie z powrotem do `pending`, bez opóźnienia i bez zużywania próby, po czym odczekuje `QUEUETY_WORKER_SLEEP` sekund przed kolejnym sprawdzeniem. Proces roboczy uruchomiony z `--once` zamiast tego kończy działanie.

Każdy proces roboczy przechowuje licznik w pamięci i odświeża go co 5 sekund na podstawie tabeli `queuety_logs`, zliczając wpisy dziennika `completed` dla modułu obsługi z ostatnich `$window` sekund. Ponieważ liczba jest obliczana na podstawie współdzielonej tabeli dzienników (oraz współdzielonej pamięci podręcznej, jeśli jest skonfigurowana), limity na poziomie modułu obsługi obowiązują we wszystkich procesach roboczych, a nie tylko w jednym. Nieudane wykonania nie są wliczane do limitu.

## Dostęp programowy

Uzyskaj bezpośredni dostęp do ogranicznika liczby żądań:

```php
$limiter = Queuety::rate_limiter();

// Register a rate limit
$limiter->register( 'call_openai', 60, 60 );

// Check whether a handler has reached its limit
$limited = $limiter->is_limited( 'call_openai' ); // true while the limit is reached

// Seconds until the current window resets
$wait = $limiter->time_until_available( 'call_openai' );
```

`register()` i `is_limited()` działają na ograniczniku w bieżącym procesie PHP. Zarejestrowanie tutaj limitu nie zmienia limitów egzekwowanych przez osobno uruchomiony proces roboczy.

## Zastosowania

- **Limity zewnętrznych API.** Dostosuj limit liczby żądań do limitu API (np. e.g, 60 żądań na minutę w OpenAI).
- **Ograniczanie liczby wysyłanych wiadomości e-mail.** Zapobiegaj wysyłaniu zbyt wielu wiadomości w krótkim czasie.
- **Ochrona zasobów.** Ogranicz liczbę obciążeń intensywnie wykorzystujących procesor, aby nie blokowały innych zadań.
