Přejít k obsahu

Omezování rychlosti

Queuety podporuje omezení rychlosti pro jednotlivé handlery, aby nedocházelo k přetížení externích API nebo jiných omezených zdrojů. Když handler dosáhne svého limitu, workeři ponechají jeho úlohy čekat a znovu je převezmou, jakmile se v okně uvolní místo.

Nastavení limitu rychlosti

Použití limitu rychlosti při odesílání úlohy:

PHP
use Queuety\Queuety;

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

Dva argumenty jsou:

  1. $max – Maximální počet spuštění povolených v okně
  2. $window – Délka okna v sekundách

Limit nastavený při odeslání se registruje pouze v procesu PHP, který úlohu odesílá. Worker běžící v samostatném procesu, například wp queuety work, jej nevidí, proto nastavte limity, které musí platit napříč procesy, v metodě config() handleru, jak je ukázáno níže (#3).

Limity rychlosti na úrovni handleru

Nastavte limity rychlosti v metodě config() handleru, aby se uplatnily při každém odeslání:

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 funguje

Limity rychlosti se sledují podle názvu handleru. Po převzetí úlohy worker zaregistruje limit handleru (z jeho config()) a zkontroluje omezovač rychlosti. Pokud handler dosáhl limitu, worker úlohu okamžitě vrátí do pending bez prodlevy a bez spotřebování pokusu, poté před dalším dotazem na úlohy počká QUEUETY_WORKER_SLEEP sekund. Worker spuštěný s --once se místo toho ukončí.

Každý worker uchovává čítač v paměti a každých 5 sekund jej obnovuje z tabulky queuety_logs, přičemž počítá záznamy protokolu completed daného handleru za posledních $window sekund. Protože počet vychází ze sdílené tabulky protokolů (a ze sdílené mezipaměti, je-li nastavena), uplatňují se limity na úrovni handleru napříč všemi workery, nejen v rámci jednoho workeru. Neúspěšná spuštění se do limitu nepočítají.

Programový přístup

Přímý přístup k omezovači rychlosti:

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() a is_limited() pracují s omezovačem v aktuálním procesu PHP. Registrace limitu zde nemění pravidla, která uplatňuje samostatně běžící worker.

Příklady použití

  • Limity externích API. Nastavte limit rychlosti podle kvóty API (e.g např. 60 požadavků za minutu u OpenAI).
  • Omezení odesílání e-mailů. Zabraňte odeslání příliš mnoha e-mailů v krátkém časovém úseku.
  • Ochrana zdrojů. Omezte handlery náročné na CPU, aby nebraly prostředky ostatním úlohám.