
# Jalankan Alur Kerja

Alur kerja dapat memulai alur kerja anak sebagai salah satu langkahnya. Alur kerja induk dijeda hingga eksekusi alur kerja anak selesai, lalu status akhir anak digabungkan ke status induk.

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

Metode `run_workflow()` menerima dua argumen:
1. Nama untuk eksekusi alur kerja
2. Instance `WorkflowBuilder` yang mendefinisikan langkah-langkah eksekusi alur kerja

## Cara kerjanya

Saat alur kerja induk mencapai langkah `run_workflow`:

1. Eksekusi alur kerja dikirim sebagai alur kerja independen dengan ID-nya sendiri
2. Alur kerja induk dijeda
3. Eksekusi alur kerja menjalankan langkah-langkahnya seperti biasa
4. Saat eksekusi alur kerja selesai, status akhirnya digabungkan ke status induk
5. Alur kerja induk dilanjutkan dengan langkah berikutnya

## Status induk/anak

Eksekusi alur kerja menerima status terakumulasi alur kerja induk saat ini sebagai payload awalnya. Artinya, langkah anak dapat mengakses data apa pun yang dihasilkan oleh langkah induk sebelumnya:

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

## Penggabungan status

Saat eksekusi alur kerja selesai, status akhirnya (tidak termasuk kunci internal seperti `_steps`, `_queue`, `_priority`, `_max_attempts`) digabungkan ke status induk. Langkah induk berikutnya melihat semua data dari langkah induk sebelumnya dan eksekusi alur kerja:

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

## Opsi eksekusi alur kerja

`on_queue()`, `with_priority()`, dan `max_attempts()` pada builder eksekusi alur kerja berlaku untuk alur kerja anak. Opsi tingkat alur kerja lainnya pada builder anak, seperti `on_cancel()`, `prune_state_after()`, `must_complete_within()`, `version()`, `idempotency_key()`, anggaran `max_*()`, dan `compensate_on_failure()`, tidak diteruskan:

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

## Eksekusi alur kerja bertingkat

Eksekusi alur kerja dapat berisi eksekusi alur kerja lainnya, sehingga memungkinkan penumpukan tanpa batas:

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