Vai al contenuto

Esegui flussi di lavoro

Un flusso di lavoro può avviare un flusso di lavoro figlio come uno dei suoi passaggi. Il flusso principale resta in pausa finché l'esecuzione del flusso figlio non termina, poi unisce lo stato finale di quest'ultimo al proprio stato.

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

Il metodo run_workflow() accetta due argomenti:

  1. Un nome per il flusso di lavoro eseguito
  2. Un'istanza WorkflowBuilder che definisce i passaggi del flusso di lavoro eseguito

Come funziona

Quando il flusso di lavoro principale raggiunge un passaggio run_workflow:

  1. Il flusso di lavoro eseguito viene avviato come flusso indipendente con un ID proprio
  2. Il flusso di lavoro principale viene messo in pausa
  3. Il flusso di lavoro eseguito completa normalmente i propri passaggi
  4. Al completamento del flusso di lavoro eseguito, il suo stato finale viene unito allo stato del flusso principale
  5. Il flusso di lavoro principale riprende dal passaggio successivo

Stato del flusso principale e del flusso figlio

Il flusso di lavoro eseguito riceve lo stato accumulato corrente del flusso principale come payload iniziale. Ciò significa che i passaggi del flusso figlio possono accedere a tutti i dati prodotti dai passaggi precedenti del flusso principale:

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

Unione dello stato

Al completamento del flusso di lavoro eseguito, il suo stato finale (escluse le chiavi interne come _steps, _queue, _priority e _max_attempts) viene unito allo stato del flusso principale. Il passaggio successivo del flusso principale può accedere a tutti i dati dei passaggi precedenti del flusso principale e del flusso di lavoro eseguito:

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

Opzioni del flusso di lavoro eseguito

Le opzioni on_queue(), with_priority() e max_attempts() del builder del flusso di lavoro eseguito si applicano al flusso figlio. Le altre opzioni a livello di flusso sul builder del figlio, come on_cancel(), prune_state_after(), must_complete_within(), version(), idempotency_key(), i limiti max_*() e compensate_on_failure(), non vengono trasferite:

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

Flussi di lavoro eseguiti annidati

I flussi di lavoro eseguiti possono contenere a loro volta altri flussi di lavoro eseguiti, consentendo un annidamento arbitrario:

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