Dinamikus for-each
Akkor használja a ->for_each() elemet, ha a munkafolyamat összeállításakor még nem ismert az ágak száma. A Queuety beolvassa a tömböt a munkafolyamat állapotából, elemenként egy ágfeladatot indít, és csak a beállított teljesülési feltétel teljesülésekor lép tovább.
A ->for_each() metódus
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 ] );
A tervezőlépés a pages értéket írja a munkafolyamat állapotába. A for-each lépés beolvassa ezt a tömböt, és elemenként egy ágfeladatot indít.
Ágkezelők
A for-each ágkezelők a Contracts\ForEachHandler interfészt valósítják meg:
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',
];
}
}
A config() elemben a backoff stratégianevet vár: exponential, linear vagy fixed. Az ott megadott próbálkozásonkénti késleltetések listája jelenleg elvész, és azonnali újrapróbálkozásra vált (#16); a próbálkozásonkénti késleltetéseket inkább a lépésdefiníció backoff mezőjében adja meg.
A $state a teljes munkafolyamat-állapotot, a $item az egyes for-each elemet, a $index pedig annak nullától kezdődő pozícióját tartalmazza.
Teljesülési módok
ForEachMode::All
A lépés csak akkor zárul le, ha minden ág sikeres. Bármely végleges ág hiba esetén a for-each lépés is hibára fut.
ForEachMode::FirstSuccess
A lépés az első sikeres ág után azonnal lezárul. A többi aktív ág felülírtként kerül félre.
ForEachMode::Quorum
A lépés akkor zárul le, ha legalább quorum ág sikeres. Ha a fennmaradó ágak már nem teljesíthetik a kvórumot, a munkafolyamat hibára fut.
Reducerek
Alapértelmezés szerint a Queuety strukturált összesítést tárol a result_key alatt:
modequorumtotalsucceededfailedsettledwinnerresultsfailures
Egyéni összesítéshez adjon át a Contracts\ForEachReducer interfészt megvalósító reducer osztályt. Az összesítés továbbra is a result_key alatt tárolódik, a reducer által visszaadott kulcsok pedig mellé kerülnek a munkafolyamat állapotába:
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,
];
}
}
A reducer kimenete ugyanúgy olvad össze a munkafolyamat állapotával, mint bármely más lépéskimenet. A for-each lezárulta után az elágazáshoz _next_step értéket is visszaadhat.
Újrapróbálkozási viselkedés
A for-each ágak egymástól függetlenül próbálkoznak újra az ágkezelő config() beállítása szerint. Ha a for-each lépés meghiúsul, és meghívja a retry_workflow() elemet, a Queuety újra kibontja a for-each lépést, és csak a még hiányzó vagy sikertelen ágakat állítja ismét sorba. A sikeres ágak eredményei a munkafolyamat állapotában maradnak.
Választás a parallel() és a for_each() között
Akkor használja a parallel() elemet, ha az áglista rögzített a kódban.
Akkor használja a for_each() elemet, ha az áglista futásidőben, a munkafolyamat állapotából derül ki, és olyan teljesülési módokra van szüksége, mint az első siker vagy a kvórum.