Ejecutar flujos de trabajo
Un flujo de trabajo puede iniciar un flujo secundario en uno de sus pasos. El principal se pausa hasta que termina la ejecución del flujo secundario y, después, combina el estado final de este con el suyo.
El método ->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' ] );
El método run_workflow() acepta dos argumentos:
- Un nombre para la ejecución del flujo de trabajo
- Una instancia de
WorkflowBuilderque define los pasos de esa ejecución
Cómo funciona
Cuando el flujo de trabajo principal llega a un paso run_workflow:
- La ejecución del flujo de trabajo se envía como un flujo independiente con su propio ID
- El flujo de trabajo principal se pausa
- La ejecución del flujo de trabajo avanza por sus pasos con normalidad
- Al completarse la ejecución, su estado final se combina con el estado del flujo principal
- El flujo de trabajo principal se reanuda en el paso siguiente
Estado del principal y del secundario
La ejecución del flujo secundario recibe el estado acumulado actual del flujo principal como carga inicial. Así, los pasos secundarios pueden acceder a los datos generados por pasos anteriores del principal:
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 [];
}
}
Combinación del estado
Cuando termina la ejecución del flujo secundario, su estado final (sin claves internas como _steps, _queue, _priority, _max_attempts) se combina con el estado del flujo principal. El paso siguiente del principal ve todos los datos de sus pasos anteriores y de la ejecución del flujo secundario:
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 [];
}
}
Opciones de ejecución del flujo de trabajo
Las opciones on_queue(), with_priority() y max_attempts() del constructor de ejecuciones se aplican al flujo secundario. Las demás opciones de nivel de flujo del constructor secundario, como on_cancel(), prune_state_after(), must_complete_within(), version(), idempotency_key(), los límites de max_*() y compensate_on_failure(), no se transfieren:
$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 );
Ejecuciones anidadas
Las ejecuciones de flujos de trabajo también pueden contener otras ejecuciones, lo que permite anidarlas sin límite:
$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 );