
# Snelheidslimieten

Queuety ondersteunt snelheidslimieten per handler om overbelasting van externe API's of andere beperkte resources te voorkomen. Wanneer een handler zijn limiet heeft bereikt, laten workers de bijbehorende taken in de wachtrij staan en pakken ze die weer op zodra er ruimte is in het venster.

## Een snelheidslimiet instellen

Pas een snelheidslimiet toe wanneer u een taak verstuurt:

```php
use Queuety\Queuety;

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

De twee argumenten zijn:
1. `$max` - Maximumaantal uitvoeringen dat binnen het venster is toegestaan
2. `$window` - Duur van het venster in seconden

Een limiet die bij het versturen wordt ingesteld, wordt alleen geregistreerd in het PHP-proces dat de taak verstuurt. Een worker in een afzonderlijk proces, zoals `wp queuety work`, ziet deze limiet niet. Stel limieten die voor meerdere processen moeten gelden daarom in de `config()` van de handler in, zoals hieronder wordt getoond ([#3](https://github.com/inline0/queuety/issues/3)).

## Snelheidslimieten op handlerniveau

Stel snelheidslimieten in de `config()`-methode van de handler in, zodat ze gelden voor elke taakverzending:

```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
        ];
    }
}
```

## Werking

Snelheidslimieten worden bijgehouden per handlernaam. Nadat een worker een taak heeft opgehaald, registreert deze de limiet van de handler (uit de `config()`) en controleert de snelheidsbegrenzer. Als de handler zijn limiet heeft bereikt, zet de worker de taak meteen terug in `pending`, zonder vertraging en zonder een poging te verbruiken. Daarna wacht de worker `QUEUETY_WORKER_SLEEP` seconden voordat deze opnieuw controleert. Een worker die is gestart met `--once` wordt in plaats daarvan beëindigd.

Elke worker houdt een teller in het geheugen bij en ververst deze elke 5 seconden aan de hand van de tabel `queuety_logs`, waarbij `completed`-logboekvermeldingen voor de handler van de afgelopen `$window` seconden worden geteld. Omdat de telling afkomstig is uit de gedeelde logboektabel (en uit de gedeelde cache, als die is ingesteld), worden limieten op handlerniveau afgedwongen voor alle workerprocessen, niet alleen binnen één worker. Mislukte uitvoeringen tellen niet mee voor de limiet.

## Programmatische toegang

Open de snelheidsbegrenzer rechtstreeks:

```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()` en `is_limited()` werken op de snelheidsbegrenzer in het huidige PHP-proces. Een limiet die u hier registreert, verandert niets aan wat een afzonderlijk draaiende worker afdwingt.

## Toepassingen

- **Limieten voor externe API.** Stem uw snelheidslimiet af op het quotum van API (e.g., 60 RPM van OpenAI).
- **E-mail beperken.** Voorkom dat u in korte tijd te veel e-mails verstuurt.
- **Resources beschermen.** Beperk handlers die veel CPU gebruiken om te voorkomen dat andere taken worden verdrongen.
