Priorita
Priorita je celé číslo, ktoré odovzdáte emit() alebo send(), a názov, ktorý k nemu priradíte cez setupPriorityQueue(). Vyššie čísla sú tie, ktoré chcete spustiť skôr. Dispatcher::DEFAULT_PRIORITY je 100.
Implementujú ju Redis drivery a FileSystemDriver. RabbitMQ, SQS a Kafka v setupPriorityQueue() vyhodia výnimku a číslo v send() ignorujú.
$driver->setupPriorityQueue('hermes_low', Dispatcher::DEFAULT_PRIORITY - 10);
$driver->setupPriorityQueue('hermes_high', Dispatcher::DEFAULT_PRIORITY + 10);
$emitter->emit(new Message('type1', ['a' => 'b']), Dispatcher::DEFAULT_PRIORITY - 10);
$emitter->emit(new Message('type1', ['c' => 'd']), Dispatcher::DEFAULT_PRIORITY + 10);Konštruktor už zaregistroval hlavný kľúč (predvolene hermes) s prioritou 100. Po týchto dvoch volaniach driver pozná tri kľúče: hermes so 100, hermes_low s 90 a hermes_high so 110.
Rovnaké dvojice zaregistrujte aj vo workeri. Nezaregistrovaná priorita vyhodí UnknownPriorityException (Unknown priority 110, ak 110 nikdy nebola nastavená).
Poradie čítania
RedisSetDriver::wait() a PredisSetDriver::wait() zoradia zaregistrované fronty podľa čísla priority, od najvyššej:
$queues = $this->queues;
krsort($queues, SORT_NUMERIC);Na poradí volaní setupPriorityQueue() nezáleží. Príklad vyššie zavolá najprv low (90) a potom high (110) a worker vyberá:
hermes_high(110)hermes(100)hermes_low(90)
Každá iterácia wait() začína znova zhora, takže čakajúca správa so 110 sa vždy spustí pred správou so 100.
Pred verziou 6.0
Do verzie 5.x drivery používali array_reverse($this->queues, true), čo číta v opačnom poradí registrácie, nie podľa čísla (issue #50). Konštruktor registruje 100 ako prvú, takže sa vždy čítala posledná a príklad vyššie vyberal 110, potom 90 a potom 100. Vo verzii 5.x registrujte len priority nad 100 vo vzostupnom poradí alebo spustite workera pre každú prioritu.
Worker pre každú prioritu
handle() môže ignorovať všetky fronty okrem tých, ktoré vymenujete:
$dispatcher->handle([Dispatcher::DEFAULT_PRIORITY + 10]);Zoznam obsahuje celé čísla. Rozhoduje in_array($priority, $priorities). Prázdny zoznam číta všetky zaregistrované fronty, od najvyššieho čísla.
Ak chcete priority škálovať samostatne, spustite tri CLI procesy:
- jeden
handle([110]) - jeden
handle([100]) - jeden
handle([90])
Procesu so 110 dajte viac replík ako ostatným. Každý proces robí SPOP len zo svojho kľúča. Nával práce s nízkou prioritou potom prácu s vysokou prioritou vôbec nezdrží.
Ďalšie obmedzenia
- Množina nie je zoradená. Dve správy v
hermes_highsa vyberajú cezSPOP, ktorý nie je FIFO. - Opakovania a presunuté odložené správy volajú
send()bez priority, takže skončia v kľúčihermesso 100. - JSON správy nemá pole priority. Worker pôvodné číslo z payloadu nezistí.
Časté otázky
Ktoré drivery podporujú priority?
RedisSetDriver, PredisSetDriver a FileSystemDriver. RabbitMQ, SQS a Kafka vyhodia v setupPriorityQueue() NotSupportedException.
Prečo sa nižšia priorita spustila skôr?
V 6.0 sa nižšie číslo spustí skôr, len keď nečaká žiadna správa s vyššou prioritou. Vo verzii 5.x Redis drivery čítali fronty v opačnom poradí registrácie, nie podľa čísla, takže priorita 100 (ktorú konštruktor registruje prvú) sa čítala posledná. Pozrite issue #50 a recept s prioritami.
Ako dosiahnuť striktné číselné poradie?
Od 6.0 drivery čítajú v číselnom poradí, od najvyššej. Vo verzii 5.x spustite jedného workera pre každú prioritu s handle([110]), handle([100]) a tak ďalej, alebo registrujte len priority nad 100 vo vzostupnom poradí.
Musím priority registrovať na oboch stranách?
Áno. Emitter aj každý worker volajú setupPriorityQueue() s rovnakými dvojicami. Neznáma priorita vyhodí UnknownPriorityException.
Sú správy v rámci jednej priority FIFO?
Nie. Každá priorita je množina v Redise a SPOP vracia náhodný prvok.