
# Omejevanje hitrosti

Queuety podpira omejevanje hitrosti za posamezne obravnavalnike, da prepreči preobremenitev zunanjih API-jev ali drugih omejenih virov. Ko obravnavalnik doseže omejitev, delavci pustijo njegova opravila v čakalni vrsti in jih znova prevzamejo, ko se v oknu sprosti prostor.

## Nastavljanje omejitve hitrosti

Uporabite omejitev hitrosti pri odpremljanju opravila:

```php
use Queuety\Queuety;

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

Argumenta sta:
1. `$max` - največje dovoljeno število izvajanj v obdobju
2. `$window` - trajanje obdobja v sekundah

Omejitev, nastavljena ob odpremi, se registrira samo v procesu PHP, ki odpošlje opravilo. Delavec v ločenem procesu, na primer `wp queuety work`, je ne vidi, zato omejitve, ki morajo veljati med procesi, nastavite v metodi `config()` obravnavalnika, kot je prikazano spodaj ([#3](https://github.com/inline0/queuety/issues/3)).

## Omejitve hitrosti na ravni obravnavalnika

Omejitve hitrosti nastavite v metodi `config()` obravnavalnika, da bodo veljale za vsako odpremo:

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

## Kako deluje

Omejitve hitrosti se spremljajo za vsako ime obravnavalnika posebej. Po prevzemu opravila delavec registrira omejitev obravnavalnika (iz `config()`) in preveri omejevalnik hitrosti. Če je obravnavalnik dosegel omejitev, delavec opravilo takoj vrne v `pending` brez zamika in brez porabe poskusa, nato pa pred naslednjim preverjanjem počaka `QUEUETY_WORKER_SLEEP` sekund. Delavec, zagnan z `--once`, se namesto tega ustavi.

Vsak delavec hrani števec v pomnilniku in ga vsakih 5 sekund osveži iz tabele `queuety_logs`, pri čemer šteje vnose dnevnika `completed` za obravnavalnika v zadnjih `$window` sekundah. Ker število izvira iz skupne tabele dnevnikov (in skupnega predpomnilnika, če je nastavljen), omejitve na ravni obravnavalnika veljajo za vse delavske procese, ne le za enega delavca. Neuspešna izvajanja se ne štejejo v omejitev.

## Programski dostop

Neposredno dostopajte do omejevalnika hitrosti:

```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()` in `is_limited()` delujeta na omejevalniku v trenutnem procesu PHP. Registracija omejitve tukaj ne spremeni omejitev za ločeno delujočega delavca.

## Primeri uporabe

- **Omejitve zunanjih storitev API.** Omejitev hitrosti uskladite s kvoto storitve API (e.g., 60 zahtev na minuto pri OpenAI).
- **Omejevanje pošiljanja e-pošte.** Preprečite pošiljanje prevelikega števila e-poštnih sporočil v kratkem obdobju.
- **Zaščita virov.** Omejite obravnavalnike, ki intenzivno uporabljajo CPE, da ne izstradajo drugih opravil.
