Hoppa till innehåll

Köra arbetsflöden

Ett arbetsflöde kan starta ett underordnat arbetsflöde som ett av sina steg. Det överordnade arbetsflödet pausar tills körningen av underarbetsflödet är klar och slår sedan samman barnets slutliga tillstånd med det överordnade tillståndet.

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

Metoden run_workflow() tar två argument:

  1. Ett namn för arbetsflödeskörningen
  2. En instans av WorkflowBuilder som definierar arbetsflödeskörningens steg

Så fungerar det

När det överordnade arbetsflödet når ett steg med run_workflow:

  1. Arbetsflödeskörningen skickas iväg som ett fristående arbetsflöde med ett eget ID
  2. Det överordnade arbetsflödet pausas
  3. Arbetsflödeskörningen går igenom sina steg som vanligt
  4. När arbetsflödeskörningen är klar slås dess slutliga tillstånd samman med det överordnade tillståndet
  5. Det överordnade arbetsflödet fortsätter med nästa steg

Tillstånd mellan överordnat och underordnat flöde

Arbetsflödeskörningen får det överordnade arbetsflödets aktuella samlade tillstånd som sin initiala nyttolast. Det innebär att underordnade steg kan komma åt data som skapats av tidigare överordnade steg:

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

Sammanfogning av tillstånd

När arbetsflödeskörningen är klar slås dess slutliga tillstånd (exklusive interna nycklar som _steps, _queue, _priority, _max_attempts) samman med det överordnade tillståndet. Nästa överordnade steg ser alla data från både tidigare överordnade steg och arbetsflödeskörningen:

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

Alternativ för arbetsflödeskörning

Alternativen on_queue(), with_priority() och max_attempts() i byggaren för arbetsflödeskörning gäller det underordnade arbetsflödet. Andra alternativ på arbetsflödesnivå i den underordnade byggaren, till exempel on_cancel(), prune_state_after(), must_complete_within(), version(), idempotency_key(), max_*()-budgetarna och compensate_on_failure(), förs inte vidare:

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

Nästlade arbetsflödeskörningar

Arbetsflödeskörningar kan själva innehålla arbetsflödeskörningar, vilket möjliggör godtyckligt djup nästling:

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