Pular para o conteúdo

Executar fluxos de trabalho

Um fluxo de trabalho pode iniciar um fluxo de trabalho filho em uma de suas etapas. O principal fica pausado até a conclusão da execução do fluxo filho e, em seguida, mescla o estado final do filho ao próprio estado.

O método ->run_workflow()

PHP
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' ] );

O método run_workflow() recebe dois argumentos:

  1. Um nome para a execução do fluxo de trabalho
  2. Uma instância de WorkflowBuilder que define as etapas dessa execução

Como funciona

Quando o fluxo de trabalho principal chega a uma etapa run_workflow:

  1. A execução do fluxo de trabalho é despachada como um fluxo independente, com seu próprio ID
  2. O fluxo de trabalho principal é pausado
  3. A execução do fluxo de trabalho percorre as etapas normalmente
  4. Quando a execução do fluxo de trabalho é concluída, seu estado final é mesclado ao estado do principal
  5. O fluxo de trabalho principal retoma a execução na próxima etapa

Estado do fluxo principal e do filho

A execução do fluxo de trabalho recebe o estado acumulado atual do principal como conteúdo inicial. Assim, as etapas filhas podem acessar dados produzidos por etapas anteriores do principal:

PHP
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 [];
    }
}

Mesclagem do estado

Quando a execução do fluxo de trabalho é concluída, seu estado final (sem as chaves internas, como _steps, _queue, _priority e _max_attempts) é mesclado ao estado do principal. A próxima etapa do principal recebe todos os dados das etapas anteriores do próprio principal e da execução do fluxo de trabalho:

PHP
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 [];
    }
}

Opções de execução do fluxo de trabalho

As opções on_queue(), with_priority() e max_attempts() do construtor de execução do fluxo de trabalho se aplicam ao fluxo filho. As outras opções no nível do fluxo de trabalho no construtor filho, como on_cancel(), prune_state_after(), must_complete_within(), version(), idempotency_key(), os limites max_*() e compensate_on_failure(), não são transferidas:

PHP
$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 );

Execuções de fluxo de trabalho aninhadas

As execuções de fluxo de trabalho também podem conter outras execuções, permitindo aninhamento arbitrário:

PHP
$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 );