Přejít k obsahu

Spouštění workflow

Workflow může v rámci jednoho ze svých kroků spustit podřízené workflow. Nadřazené workflow se pozastaví, dokud se spuštěné workflow nedokončí, a pak sloučí jeho konečný stav do svého stavu.

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

Metoda run_workflow() přijímá dva argumenty:

  1. Název spuštěného workflow
  2. Instanci WorkflowBuilder, která definuje jeho kroky

Jak to funguje

Když nadřazené workflow dosáhne kroku run_workflow:

  1. Spuštěné workflow se zařadí jako nezávislé workflow s vlastním ID
  2. Nadřazené workflow se pozastaví
  3. Spuštěné workflow běžně provede své kroky
  4. Po dokončení se jeho konečný stav sloučí se stavem nadřazeného workflow
  5. Nadřazené workflow pokračuje dalším krokem

Stav nadřazeného a podřízeného workflow

Spuštěné workflow obdrží aktuální nashromážděný stav nadřazeného workflow jako počáteční data. Podřízené kroky tak mají přístup ke všem datům vytvořeným předchozími kroky nadřazeného workflow:

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

Sloučení stavu

Po dokončení spuštěného workflow se jeho konečný stav (bez interních klíčů, jako jsou _steps, _queue, _priority, _max_attempts) sloučí se stavem nadřazeného workflow. Další nadřazený krok uvidí všechna data z dřívějších nadřazených kroků i ze spuštěného workflow:

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

Možnosti spuštěného workflow

Možnosti on_queue(), with_priority() a max_attempts() nástroje pro sestavení spuštěného workflow se vztahují na podřízené workflow. Ostatní možnosti na úrovni workflow v nástroji pro sestavení podřízeného workflow, například on_cancel(), prune_state_after(), must_complete_within(), version(), idempotency_key(), rozpočty max_*() a compensate_on_failure(), se nepřenášejí:

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

Vnořená spuštěná workflow

Spuštěná workflow mohou sama obsahovat další spuštěná workflow, což umožňuje libovolné vnořování:

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