並列ステップ
複数のステップを同時に実行できる場合があります。->parallel()メソッドは、ハンドラーのグループを並行してディスパッチします。すべての並列ハンドラーが完了してから、ワークフローが次に進みます。
->parallel()メソッド
PHP
use Queuety\Queuety;
Queuety::workflow( 'enrich_profile' )
->then( FetchUserHandler::class )
->parallel( [
FetchSocialProfileHandler::class,
FetchPaymentHistoryHandler::class,
FetchActivityLogHandler::class,
] )
->then( MergeAndSaveHandler::class )
->dispatch( [ 'user_id' => 42 ] );
この例では、次の順に実行されます。
- 最初に
FetchUserHandlerが実行される(逐次) - 3つのハンドラーが並行して実行される
- 3つすべてが完了した後に
MergeAndSaveHandlerが実行される(逐次)
仕組み
並列ステップに到達すると、Queuetyはグループ内の各ハンドラーに1つずつジョブをディスパッチします。各ジョブは現在のワークフロー状態を受け取り、独立して実行されます。ワークフローは未完了の並列ジョブ数を追跡し、すべて完了してから次のステップに進みます。
各並列ハンドラーの戻り値はワークフロー状態にマージされます。複数のハンドラーが同じキーを返す場合、最後に完了したハンドラーの値が使われます。
状態のマージ
各並列ハンドラーは、共有ワークフロー状態にマージされるデータを返します。
PHP
class FetchSocialProfileHandler implements Step {
public function handle( array $state ): array {
$profile = fetch_social_api( $state['user_id'] );
return [ 'social_profile' => $profile ];
}
public function config(): array {
return [];
}
}
class FetchPaymentHistoryHandler implements Step {
public function handle( array $state ): array {
$payments = fetch_payment_api( $state['user_id'] );
return [ 'payment_history' => $payments ];
}
public function config(): array {
return [];
}
}
並列ステップの完了後、状態にはsocial_profileとpayment_historyの両方が含まれ、次の逐次ステップからすべてを参照できます。
逐次処理と並列処理を組み合わせる
->then()呼び出しと->parallel()呼び出しは自由に組み合わせられます。
PHP
Queuety::workflow( 'complex_pipeline' )
->then( SetupHandler::class ) // sequential
->parallel( [ TaskA::class, TaskB::class ] ) // parallel
->then( IntermediateHandler::class ) // sequential
->parallel( [ TaskC::class, TaskD::class ] ) // parallel
->then( FinalizeHandler::class ) // sequential
->dispatch( $payload );
エラー処理
並列グループ内のハンドラーが失敗すると、そのハンドラーには通常の再試行ロジックが適用されます。すでに完了した他の並列ハンドラーは再実行されません。失敗したハンドラーが成功すると、ワークフローは先へ進みます。再試行を使い切ってそのジョブが埋められると、ワークフローは失敗としてマークされ、残りのブランチジョブも埋められます。失敗したステップを再実行するには、retry_workflow()を使います。