
# Dependensi Alur Kerja

Gunakan penantian dependensi alur kerja saat satu alur kerja tingkat atas hanya boleh berlanjut setelah alur kerja lain selesai. Ini memungkinkan koordinasi lintas alur kerja tanpa memaksakan semuanya ke dalam satu definisi alur kerja yang sangat besar.

Penantian ini sangat cocok dipadukan dengan [Serah Terima Asinkron](https://queuety.inline0.dev/id/docs/workflows/async-handoffs), saat satu alur kerja terlebih dahulu memulai alur kerja anak yang independen, lalu menunggunya kemudian.

Untuk contoh planner/executor yang lebih lengkap, lihat [Orkestrasi Agen](https://queuety.inline0.dev/id/docs/workflows/agent-orchestration).

Queuety menyediakan tiga metode pembuat:

- `wait_for_workflow()` untuk satu alur kerja
- `wait_for_workflows()` untuk beberapa alur kerja dengan semantik `all`, `any`, atau `quorum`
- `wait_for_workflow_group()` saat ID alur kerja berasal dari grup yang dimulai sebelumnya

## Menunggu satu alur kerja

```php
$research_id = Queuety::workflow( 'research_run' )
    ->then( PlanResearchStep::class )
    ->for_each( 'tasks', ExecuteResearchTask::class, 'results' )
    ->dispatch( [ 'brief_id' => 42 ] );

$editorial_id = Queuety::workflow( 'editorial_run' )
    ->wait_for_workflow( $research_id, 'research' )
    ->then( DraftBriefStep::class )
    ->dispatch();
```

Saat `research_run` selesai, `editorial_run` dilanjutkan. Jika `result_key` ditetapkan, status dependensi yang selesai disimpan di bawah kunci tersebut:

```php
$state['research']; // public state from the completed research workflow
```

Tanpa `result_key`, status publik alur kerja dependensi digabungkan ke status tingkat atas alur kerja yang menunggu.

## Menunggu beberapa alur kerja

```php
use Queuety\Enums\WaitMode;

Queuety::workflow( 'synthesis_run' )
    ->wait_for_workflows(
        [ $research_id, $editorial_id, $legal_id ],
        WaitMode::All,
        'dependencies'
    )
    ->then( PublishPacketStep::class )
    ->dispatch();
```

- `WaitMode::All` hanya dilanjutkan setelah semua alur kerja yang tercantum selesai.
- `WaitMode::Any` dilanjutkan saat alur kerja pertama yang tercantum selesai.
- `WaitMode::Quorum` dilanjutkan setelah sejumlah alur kerja yang diwajibkan berhasil diselesaikan.

```php
Queuety::workflow( 'synthesis_run' )
    ->wait_for_workflows(
        [ $research_id, $editorial_id, $legal_id ],
        WaitMode::Quorum,
        'dependencies',
        quorum: 2,
    )
    ->then( PublishPacketStep::class )
    ->dispatch();
```

Dengan `result_key`, penantian beberapa alur kerja menyimpan status dependensi yang telah selesai berdasarkan ID alur kerja:

```php
[
    '42' => [ 'summary' => '...' ],
    '43' => [ 'summary' => '...' ],
]
```

Tanpa `result_key`, status dependensi yang selesai digabungkan ke status tingkat atas alur kerja yang menunggu sesuai urutan dependensi.

## Menentukan ID dependensi dari status alur kerja

Anda dapat menunda penetapan daftar dependensi hingga waktu berjalan dengan membaca ID alur kerja dari status publik:

```php
Queuety::workflow( 'agent_follow_up' )
    ->wait_for_workflow( 'parent_workflow_id', 'parent' )
    ->then( FinalizeAgentRunStep::class )
    ->dispatch( [ 'parent_workflow_id' => $workflow_id ] );
```

Untuk beberapa dependensi:

```php
Queuety::workflow( 'aggregator' )
    ->wait_for_workflows( 'dependency_ids', WaitMode::Any, 'winner' )
    ->dispatch( [ 'dependency_ids' => [ 12, 18, 22 ] ] );
```

## Menunggu grup alur kerja yang telah dimulai

Jika langkah `start_workflows()` atau `start_agents()` sebelumnya menyimpan kunci grup persisten, Anda dapat langsung menunggu grup tersebut alih-alih mengalirkan ID alur kerja melalui status publik sendiri.

```php
Queuety::workflow( 'brief_research' )
    ->then( PlanTopicsStep::class )
    ->start_agents( 'agent_tasks', $agent_run, group_key: 'researchers' )
    ->wait_for_agent_group( 'researchers', WaitMode::Quorum, 2, 'agent_results' )
    ->then( SynthesizeBriefStep::class )
    ->dispatch();
```

## Yang terjadi selama menunggu

Saat alur kerja mencapai salah satu langkah ini, statusnya berubah menjadi `waiting_for_workflows`. Tidak ada worker yang tetap terhubung selama alur kerja menunggu.

```php
$state = Queuety::workflow_status( $workflow_id );
echo $state->status->value; // 'waiting_for_workflows'
echo $state->wait_type;     // 'workflow'
print_r( $state->waiting_for ); // ['42', '43']
```

Jika suatu dependensi sudah selesai sebelum langkah penantian tercapai, alur kerja langsung berlanjut.

## Semantik kegagalan

Penantian dependensi alur kerja berorientasi pada keberhasilan:

- `wait_for_workflow()` dan `WaitMode::All` gagal jika dependensi wajib mana pun gagal atau dibatalkan.
- `WaitMode::Any` gagal hanya jika semua dependensi mencapai status terminal dan tidak ada yang berhasil diselesaikan.
- `WaitMode::Quorum` gagal jika alur kerja aktif yang tersisa tidak lagi dapat memenuhi kuorum yang diwajibkan.

Ini membuat penantian alur kerja berguna untuk sistem planner/executor, ketika satu alur kerja dapat menghasilkan pekerjaan untuk alur kerja lain, lalu menunggu hasil `all` atau cabang pertama yang berhasil selesai.
