Deferrery a úlohy vo fronte
Deferrer číta aktuálny čas a pri dosiahnutí limitu vykoná čakanie.
SleepDeferrer
Predvolený. Číta aktuálny čas v milisekundách a čaká cez Illuminate\Support\Sleep — ten môžete v testoch nahradiť fake (pozrite Testovanie).
ReleaseDeferrer
Na použitie v úlohe vo fronte: namiesto blokovania workera vráti úlohu do fronty s vypočítaným oneskorením (zaokrúhleným nahor na celé sekundy, takže sa úloha nikdy nespustí predčasne) a vyhodí JobReleasedException — s kľúčom limitu a úlohou —, ktorá ukončí aktuálny pokus bez odoslania požiadavky. Zapnete ho cez RateLimits::releasingJob() — skratku pre RateLimits::usingDeferrer(new ReleaseDeferrer($job)):
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;
// inside a queued job's handle(), $this uses Illuminate\Queue\InteractsWithQueue
$rateLimit = RateLimits::releasingJob($this)->perSecond(5);
Http::withMiddleware($rateLimit)->get('https://api.example.com/things');Pridajte úlohe middleware HandlesRateLimitRelease: pokus ukončí ako bežný návrat, takže ho worker nenahlási, nespustí JobExceptionOccurred a nezapočíta ho do $maxExceptions úlohy. Kompletná úloha — so zdieľaným úložiskom, aby každý beh čítal ten istý limit:
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Http;
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;
use RoundlyConsulting\HttpClientRateLimits\Jobs\Middleware\HandlesRateLimitRelease;
final class SyncThings implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable;
// Every release counts as an attempt: allow enough (or define retryUntil()).
public int $tries = 10;
public function middleware(): array
{
return [new HandlesRateLimitRelease];
}
public function handle(): void
{
$rateLimit = RateLimits::releasingJob($this)->perSecond(5);
Http::withMiddleware($rateLimit)->get('https://api.example.com/things');
}
}Ako pri každej úlohe, ktorú Laravel vráti do fronty, každé vrátenie spotrebuje jeden z jej $tries, preto ich nastavte dostatok. Middleware zachytí len vrátenie vlastnej úlohy; výnimka inej úlohy sa šíri ďalej. Bez middlewaru výnimku zachyťte sami — úloha je už späť vo fronte:
use RoundlyConsulting\HttpClientRateLimits\Exceptions\JobReleasedException;
try {
Http::withMiddleware(RateLimits::releasingJob($this)->perSecond(5))->get($url);
} catch (JobReleasedException) {
return;
}Úloha musí mať metódu release() od Laravelu (napr. cez InteractsWithQueue); inak releasingJob() — konštruktor ReleaseDeferrer — vyhodí InvalidDeferrerException.
Vlastný deferrer
Implementujte kontrakt Deferrer — timestamp() v milisekundách a defer(int $ms, string $key). Po čakaní limiter znova overí úložisko; deferrer, ktorého hodiny sa neposunuli (simulované čakanie), berie za slovo:
namespace RoundlyConsulting\HttpClientRateLimits\Deferrer;
interface Deferrer
{
// "Now" in milliseconds — the clock every window is measured on.
public function timestamp(): int;
// Wait $ms before the request for limit $key may go; the limiter then re-checks the store.
public function defer(int $ms, string $key): void;
}Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.