Dynamický cyklus For-Each
Použite ->for_each(), keď pri zostavovaní workflowu ešte nepoznáte počet vetiev. Queuety načíta z poľa stavu workflowu pole položiek, pre každú odošle úlohu vetvy a pokračuje až po splnení nastavenej podmienky dokončenia.
Metóda ->for_each()
use Queuety\Contracts\ForEachHandler;
use Queuety\Contracts\ForEachReducer;
use Queuety\Enums\ForEachMode;
use Queuety\Queuety;
Queuety::workflow( 'index_site' )
->then( PlanPagesStep::class )
->for_each(
items_key: 'pages',
handler_class: IndexPageStep::class,
result_key: 'page_results',
mode: ForEachMode::Quorum,
quorum: 2,
reducer_class: IndexSummaryReducer::class,
name: 'index_pages',
)
->then( PublishIndexStep::class )
->dispatch( [ 'site_id' => 42 ] );
Plánovací krok zapíše pages do stavu workflowu. Krok for-each načíta toto pole a pre každú položku odošle úlohu vetvy.
Obslužné rutiny vetiev
Obslužné rutiny vetiev cyklu for-each implementujú Contracts\ForEachHandler:
use Queuety\Contracts\ForEachHandler;
final class IndexPageStep implements ForEachHandler {
public function handle_item( array $state, mixed $item, int $index ): array {
$page = is_array( $item ) ? $item : [ 'url' => (string) $item ];
return [
'url' => $page['url'],
'title' => fetch_title( $page['url'] ),
'index' => $index,
];
}
public function config(): array {
return [
'max_attempts' => 3,
'backoff' => 'exponential',
];
}
}
V config() prijíma backoff názov stratégie: exponential, linear alebo fixed. Zoznam oneskorení pre jednotlivé pokusy sa tam momentálne zahodí a opakovania sa vykonajú okamžite (#16); oneskorenia pre jednotlivé pokusy nastavte v backoff definície kroku.
$state obsahuje celý stav workflowu, $item označuje jednotlivú položku cyklu for-each a $index jej pozíciu počítanú od nuly.
Režimy dokončenia
ForEachMode::All
Krok sa dokončí až po úspechu všetkých vetiev. Akákoľvek trvalá chyba vetvy spôsobí zlyhanie kroku for-each.
ForEachMode::FirstSuccess
Krok sa dokončí hneď po úspechu prvej vetvy. Zostávajúce aktívne vetvy sa označia ako nahradené a presunú do archívu.
ForEachMode::Quorum
Krok sa dokončí, keď uspeje aspoň quorum vetiev. Ak zostávajúce vetvy už nedokážu splniť kvórum, workflow zlyhá.
Reduktory
Predvolene Queuety ukladá štruktúrovaný súhrn pod kľúčom result_key:
modequorumtotalsucceededfailedsettledwinnerresultsfailures
Ak chcete vlastný súhrn, odovzdajte triedu reduktora implementujúcu Contracts\ForEachReducer. Súhrn sa stále ukladá pod kľúčom result_key a kľúče vrátené reduktorom sa vedľa neho zlúčia do stavu workflowu:
use Queuety\Contracts\ForEachReducer;
final class IndexSummaryReducer implements ForEachReducer {
public function reduce( array $state, array $for_each ): array {
return [
'indexed_count' => count( $for_each['results'] ),
'winning_url' => $for_each['winner']['output']['url'] ?? null,
];
}
}
Výstup reduktora sa zlúči do stavu workflowu rovnako ako výstup každého iného kroku. Môže tiež vrátiť _next_step, aby sa po dokončení cyklu for-each spustila ďalšia vetva.
Správanie pri opakovaní
Vetvy cyklu for-each sa opakujú samostatne podľa config() obslužnej rutiny vetvy. Ak krok for-each zlyhá a zavoláte retry_workflow(), Queuety znova rozšíri krok for-each a do frontu zaradí iba chýbajúce alebo neúspešné vetvy. Výsledky úspešných vetiev zostanú v stave workflowu.
Výber medzi parallel() a for_each()
Použite parallel(), keď je zoznam vetiev pevne daný v kóde.
Použite for_each(), keď sa zoznam vetiev zisťuje počas behu zo stavu workflowu a potrebujete režim dokončenia, napríklad prvý úspech alebo kvórum.