
# 运行工作流

工作流可以将子工作流作为其中一个步骤启动。父工作流会暂停，直到运行工作流完成，然后将子工作流的最终状态合并到父工作流的状态中。

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