
# Spartos ribojimas

Queuety palaiko kiekvienos apdorojimo funkcijos spartos ribojimą, kad nebūtų perkrautos išorinės API ar kiti riboti ištekliai. Apdorojimo funkcijai pasiekus ribą, vykdytojai palieka jos užduotis eilėje ir vėl paima jas, kai lange atsiranda laisvos vietos.

## Spartos ribos nustatymas

Nustatykite spartos ribą siųsdami užduotį:

```php
use Queuety\Queuety;

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

Du argumentai:
1. `$max` – didžiausias leidžiamas vykdymų skaičius per langą
2. `$window` – lango trukmė sekundėmis

Siuntimo metu nustatyta riba užregistruojama tik procese PHP, kuris išsiunčia užduotį. Atskirame procese veikiantis vykdytojas, pavyzdžiui, `wp queuety work`, jos nemato, todėl tarp procesų galiojančias ribas nustatykite apdorojimo funkcijos `config()`, kaip parodyta toliau ([#3](https://github.com/inline0/queuety/issues/3)).

## Apdorojimo funkcijos lygmens spartos ribos

Nustatykite spartos ribas apdorojimo funkcijos metode `config()`, kad jos būtų taikomos kiekvienai siunčiamai užduočiai:

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

## Kaip tai veikia

Spartos ribos sekamos pagal apdorojimo funkcijos pavadinimą. Perėmęs užduotį, vykdytojas užregistruoja apdorojimo funkcijos ribą (iš jos `config()`) ir patikrina spartos ribotuvą. Apdorojimo funkcijai pasiekus ribą, vykdytojas iškart grąžina užduotį į `pending` be delsos ir neįskaičiuodamas bandymo, tada prieš kitą patikrinimą laukia `QUEUETY_WORKER_SLEEP` sekundes. Jei vykdytojas paleistas su `--once`, jis uždaromas.

Kiekvienas vykdytojas saugo atmintyje esantį skaitiklį ir kas 5 sekundes jį atnaujina iš lentelės `queuety_logs`, skaičiuodamas apdorojimo funkcijos `completed` žurnalo įrašus per pastarąsias `$window` sekundes. Kadangi skaičius gaunamas iš bendros žurnalų lentelės (ir bendros podėlio talpyklos, jei ji sukonfigūruota), apdorojimo funkcijų lygmens ribos taikomos visiems vykdytojo procesams, o ne tik vienam vykdytojui. Nesėkmingi vykdymai į ribą neįskaičiuojami.

## Programinė prieiga

Tiesiogiai pasiekite spartos ribotuvą:

```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()` ir `is_limited()` veikia dabartinio PHP proceso ribotuve. Čia užregistruota riba nepakeičia atskirai veikiančiam vykdytojui taikomos ribos.

## Naudojimo atvejai

- **Išorinių API ribos.** Suderinkite spartos ribą su API kvota (e.g., 60 užklausų per minutę, kurias leidžia OpenAI).
- **El. pašto siuntimo ribojimas.** Neleiskite per trumpą laiką išsiųsti per daug el. laiškų.
- **Išteklių apsauga.** Apribokite daug procesoriaus išteklių naudojančias apdorojimo funkcijas, kad jos netrukdytų kitoms užduotims.
