Exécuter des workflows
Un workflow peut lancer un workflow enfant comme l’une de ses étapes. Le parent se met en pause jusqu’à la fin de l’exécution du workflow enfant, puis fusionne l’état final de l’enfant dans le sien.
La méthode ->run_workflow()
use Queuety\Queuety;
$enrichment = Queuety::workflow( 'enrich_user' )
->then( FetchSocialHandler::class )
->then( FetchCreditScoreHandler::class );
Queuety::workflow( 'onboarding' )
->then( CreateAccountHandler::class )
->run_workflow( 'enrich_user', $enrichment )
->then( SendWelcomeEmailHandler::class )
->dispatch( [ 'email' => 'user@example.com' ] );
La méthode run_workflow() prend deux arguments :
- Un nom pour l’exécution du workflow
- Une instance
WorkflowBuilderqui définit les étapes de l’exécution
Fonctionnement
Lorsque le workflow parent atteint une étape run_workflow :
- L’exécution du workflow est lancée comme workflow indépendant avec son propre identifiant
- Le workflow parent se met en pause
- Le workflow enfant exécute ses étapes normalement
- À la fin de son exécution, son état final est fusionné dans celui du parent
- Le workflow parent reprend à l’étape suivante
État parent/enfant
Le workflow enfant reçoit l’état cumulé actuel du parent comme charge utile initiale. Ses étapes peuvent donc accéder à toutes les données produites par les étapes précédentes du parent :
class CreateAccountHandler implements Step {
public function handle( array $state ): array {
$user_id = wp_create_user( $state['email'], wp_generate_password() );
return [ 'user_id' => $user_id ];
}
public function config(): array {
return [];
}
}
// This run-workflow step can access 'user_id' from the parent
class FetchSocialHandler implements Step {
public function handle( array $state ): array {
$profile = fetch_social_profile( $state['user_id'] );
return [ 'social_data' => $profile ];
}
public function config(): array {
return [];
}
}
Fusion de l’état
À la fin de l’exécution du workflow enfant, son état final (à l’exception des clés internes telles que _steps, _queue, _priority, _max_attempts) est fusionné dans l’état du parent. L’étape suivante du parent voit toutes les données des étapes précédentes du parent et du workflow enfant :
class SendWelcomeEmailHandler implements Step {
public function handle( array $state ): array {
// Has access to:
// - $state['email'] (from initial dispatch)
// - $state['user_id'] (from CreateAccountHandler)
// - $state['social_data'] (from run-workflow's FetchSocialHandler)
// - $state['credit_score'] (from run-workflow's FetchCreditScoreHandler)
send_welcome_email( $state['email'], $state['social_data'] );
return [ 'welcome_sent' => true ];
}
public function config(): array {
return [];
}
}
Options d’exécution du workflow enfant
Les options on_queue(), with_priority() et max_attempts() du générateur d’exécution du workflow s’appliquent au workflow enfant. Les autres options au niveau du workflow sur le générateur enfant, comme on_cancel(), prune_state_after(), must_complete_within(), version(), idempotency_key(), les budgets max_*() et compensate_on_failure(), ne sont pas reprises :
$sub = Queuety::workflow( 'heavy_processing' )
->on_queue( 'background' )
->with_priority( Priority::Normal )
->max_attempts( 5 )
->then( StepA::class )
->then( StepB::class );
Queuety::workflow( 'parent' )
->run_workflow( 'heavy', $sub )
->then( FinalStep::class )
->dispatch( $payload );
Exécutions de workflows imbriquées
Les workflows enfants peuvent eux-mêmes contenir des workflows enfants, ce qui permet une imbrication arbitraire :
$inner = Queuety::workflow( 'inner' )
->then( InnerStepA::class )
->then( InnerStepB::class );
$middle = Queuety::workflow( 'middle' )
->then( MiddleStepA::class )
->run_workflow( 'inner', $inner )
->then( MiddleStepB::class );
Queuety::workflow( 'outer' )
->then( OuterStepA::class )
->run_workflow( 'middle', $middle )
->then( OuterStepB::class )
->dispatch( $payload );