
# Langkah Paralel

Terkadang, beberapa langkah dapat berjalan pada saat yang sama. Metode `->parallel()` mengirimkan sekelompok handler secara bersamaan. Alur kerja hanya berlanjut setelah semua handler paralel selesai.

## Metode `->parallel()`

```php
use Queuety\Queuety;

Queuety::workflow( 'enrich_profile' )
    ->then( FetchUserHandler::class )
    ->parallel( [
        FetchSocialProfileHandler::class,
        FetchPaymentHistoryHandler::class,
        FetchActivityLogHandler::class,
    ] )
    ->then( MergeAndSaveHandler::class )
    ->dispatch( [ 'user_id' => 42 ] );
```

Dalam contoh ini:
1. `FetchUserHandler` berjalan terlebih dahulu (berurutan)
2. Tiga handler berjalan secara bersamaan (paralel)
3. `MergeAndSaveHandler` berjalan setelah ketiganya selesai (berurutan)

## Cara kerjanya

Saat mencapai langkah paralel, Queuety mengirim satu tugas untuk setiap handler dalam grup. Setiap tugas menerima status alur kerja saat ini dan berjalan secara mandiri. Alur kerja melacak jumlah tugas paralel yang belum selesai dan hanya berlanjut ke langkah berikutnya setelah semuanya selesai.

Nilai yang dikembalikan setiap handler paralel digabungkan ke dalam status alur kerja. Jika beberapa handler mengembalikan kunci yang sama, yang terakhir selesai akan menang.

## Penggabungan status

Setiap handler paralel mengembalikan data yang kemudian digabungkan ke dalam status alur kerja bersama:

```php
class FetchSocialProfileHandler implements Step {
    public function handle( array $state ): array {
        $profile = fetch_social_api( $state['user_id'] );
        return [ 'social_profile' => $profile ];
    }

    public function config(): array {
        return [];
    }
}

class FetchPaymentHistoryHandler implements Step {
    public function handle( array $state ): array {
        $payments = fetch_payment_api( $state['user_id'] );
        return [ 'payment_history' => $payments ];
    }

    public function config(): array {
        return [];
    }
}
```

Setelah langkah paralel selesai, status berisi `social_profile` dan `payment_history`, dan langkah berurutan berikutnya dapat mengakses semuanya.

## Memadukan langkah berurutan dan paralel

Anda bebas memadukan pemanggilan `->then()` dan `->parallel()`:

```php
Queuety::workflow( 'complex_pipeline' )
    ->then( SetupHandler::class )               // sequential
    ->parallel( [ TaskA::class, TaskB::class ] ) // parallel
    ->then( IntermediateHandler::class )         // sequential
    ->parallel( [ TaskC::class, TaskD::class ] ) // parallel
    ->then( FinalizeHandler::class )             // sequential
    ->dispatch( $payload );
```

## Penanganan error

Jika ada handler dalam grup paralel yang gagal, alur kerja mengikuti logika percobaan ulang normal untuk handler tersebut. Handler paralel lain yang sudah selesai tidak dijalankan ulang. Setelah handler yang gagal berhasil, alur kerja berlanjut. Jika percobaan ulangnya habis dan tugasnya dikubur, alur kerja ditandai gagal dan tugas cabang yang tersisa dikubur; gunakan `retry_workflow()` untuk menjalankan kembali langkah yang gagal.
