Dynamický cyklus for-each
Použijte ->for_each(), když při sestavování workflow není znám počet větví. Queuety načte pole ze stavu workflow, spustí úlohu větve pro každou položku a pokračuje, až je splněna nastavená podmínka dokončení.
Metoda ->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 ] );
Krok plánovače zapíše pages do stavu workflow. Krok cyklu for-each toto pole načte a spustí úlohu větve pro každou položku.
Obslužné rutiny větví
Obslužné rutiny větví 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() přijímá backoff název strategie: exponential, linear nebo fixed. Seznam prodlev mezi pokusy se nyní zahazuje a vede k okamžitým opakováním (#16); prodlevy mezi pokusy místo toho nastavte v backoff definice kroku.
$state obsahuje úplný stav workflow, $item je jednotlivá položka cyklu for-each a $index je její pozice počítaná od nuly.
Režimy dokončení
ForEachMode::All
Krok skončí až po úspěchu všech větví. Trvalé selhání kterékoli větve způsobí selhání cyklu for-each.
ForEachMode::FirstSuccess
Krok skončí, jakmile uspěje první větev. Zbývající aktivní větve se označí jako překonané.
ForEachMode::Quorum
Krok skončí, jakmile uspěje alespoň quorum větví. Pokud zbývající větve už nemohou splnit kvórum, workflow selže.
Reduktory
Ve výchozím nastavení Queuety ukládá strukturovaný souhrn pod klíčem result_key:
modequorumtotalsucceededfailedsettledwinnerresultsfailures
Chcete-li vlastní souhrn, předejte třídu reduktoru implementující Contracts\ForEachReducer. Souhrn se stále ukládá pod klíčem result_key a klíče vrácené reduktorem se vedle něj sloučí se stavem workflow:
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 reduktoru se stejně jako výstup jiného kroku sloučí se stavem workflow. Může také vrátit _next_step pro větvení po skončení cyklu for-each.
Opakování při chybě
Větve cyklu for-each opakují pokusy nezávisle podle config() obslužné rutiny větve. Pokud krok cyklu for-each selže a zavoláte retry_workflow(), Queuety cyklus znovu rozbalí a do fronty zařadí pouze chybějící nebo neúspěšné větve. Výsledky úspěšných větví zůstanou ve stavu workflow.
Volba mezi parallel() a for_each()
Použijte parallel(), pokud je seznam větví pevně daný v kódu.
Použijte for_each(), pokud se seznam větví zjišťuje za běhu ze stavu workflow a potřebujete režim dokončení, například při prvním úspěchu nebo při dosažení kvóra.