Перейти до вмісту

Запуск робочих процесів

Робочий процес може запустити дочірній робочий процес як один зі своїх кроків. Батьківський процес призупиняється, доки вкладений робочий процес не завершиться, а потім об’єднує кінцевий стан дочірнього процесу зі своїм станом.

Метод ->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' ] );

Метод run_workflow() приймає два аргументи:

  1. Назву вкладеного робочого процесу
  2. Екземпляр WorkflowBuilder, що визначає його кроки

Як це працює

Коли батьківський робочий процес доходить до кроку run_workflow:

  1. Вкладений робочий процес запускається як незалежний процес із власним ID
  2. Батьківський робочий процес призупиняється
  3. Вкладений робочий процес проходить свої кроки звичайним чином
  4. Після завершення вкладеного робочого процесу його кінцевий стан об’єднується зі станом батьківського процесу
  5. Батьківський робочий процес продовжується з наступного кроку

Стан батьківського й дочірнього процесів

Вкладений робочий процес отримує поточний накопичений стан батьківського процесу як початкові дані. Це означає, що дочірні кроки мають доступ до даних, створених на попередніх кроках батьківського процесу:

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

Об’єднання стану

Після завершення вкладеного робочого процесу його кінцевий стан (без внутрішніх ключів, як-от _steps, _queue, _priority, _max_attempts) об’єднується зі станом батьківського процесу. Наступний крок батьківського процесу отримує всі дані з попередніх кроків як батьківського, так і вкладеного робочого процесу:

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

Параметри вкладеного робочого процесу

Параметри on_queue(), with_priority() і max_attempts() побудовника вкладеного робочого процесу застосовуються до дочірнього процесу. Інші параметри рівня робочого процесу дочірнього побудовника, як-от on_cancel(), prune_state_after(), must_complete_within(), version(), idempotency_key(), обмеження бюджету max_*() і compensate_on_failure(), не передаються:

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

Вкладені робочі процеси

Вкладені робочі процеси можуть містити інші вкладені робочі процеси, що дає змогу створювати довільні рівні вкладеності:

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