
# Worker Paralel

Greph membagi pemindaian teks dan AST ke sekumpulan worker jika volume pekerjaan cukup besar untuk sepadan dengan overhead-nya. Kumpulan ini dibangun menggunakan `pcntl_fork()` dan beralih ke eksekusi dalam proses yang sama jika `ext-pcntl` tidak tersedia (Windows, beberapa lingkungan PaaS, hosting terbatas).

## Mengaktifkan Pemindaian Paralel

Tetapkan `-j N` pada CLI atau `jobs: N` pada objek opsi yang sesuai:

```bash
./vendor/bin/greph -F -j 8 "function" src
./vendor/bin/greph -p '$obj->$method($$$ARGS)' -j 4 src
./vendor/bin/rg --threads 8 -F "function" src
./vendor/bin/sg run --threads 8 --pattern '$obj->$method($$$ARGS)' src
```

```php
use Greph\Greph;
use Greph\Text\TextSearchOptions;

Greph::searchText(
    'function',
    'src',
    new TextSearchOptions(fixedString: true, jobs: 8),
);
```

## Kapan Eksekusi Paralel Dimulai

Greph tidak selalu menjalankan proses secara paralel. Membuat cabang N proses dan bolak-balik mengirim hasilnya melalui pipe membutuhkan overhead, dan pada daftar file kecil overhead tersebut lebih besar daripada biaya pencarian itu sendiri. Sebagai gantinya, facade menghitung ambang berdasarkan jumlah pekerjaan, mode pencarian, dan bentuk pola. Hanya daftar file yang melampaui ambang yang dikirim ke kumpulan worker.

Heuristik saat ini (di `Greph\Greph::shouldUseTextWorkers` dan komponen terkait):

- Proses dengan satu pekerjaan (`-j 1`) selalu berjalan dalam proses yang sama.
- Pemindaian teks default memerlukan sekitar `jobs * 2_000` file sebelum kumpulan worker diaktifkan.
- Mode jumlah, file yang cocok, dan file yang tidak cocok menurunkan ambang menjadi sekitar `jobs * 750` karena pekerjaan per file lebih ringan.
- Pola string tetap yang pendek dan berbentuk pengenal menaikkan ambang menjadi sekitar `jobs * 4_000` karena jalur cepat literal sudah sangat ringan sehingga membuat cabang proses jarang sepadan.
- Pencarian dan penulisan ulang AST menggunakan ambang `jobs * 750`.

Angka-angka ini adalah heuristik, bukan jaminan. Angka tersebut disetel berdasarkan korpus tolok ukur WordPress dan dapat ditinjau ulang.

## Cara Kerja Kumpulan Worker

`Greph\Parallel\WorkSplitter` membagi daftar file menjadi N bagian. `Greph\Parallel\WorkerPool` membuat satu proses worker untuk setiap bagian; setiap worker menjalankan closure yang sama pada bagiannya, lalu `Greph\Parallel\ResultCollector` membaca kembali hasil serialisasi melalui pasangan socket Unix untuk setiap worker. Proses induk menunggu semua worker, lalu menggabungkan dan mengurutkan ulang seluruh hasil agar urutan keluaran tetap sama, terlepas dari pembagian pekerjaan.

Untuk mode teks, kumpulan worker menggunakan codec khusus pada wire (`Greph\Text\TextResultCodec`) agar payload serialisasi tetap ringkas. Mode AST menggunakan PHP's `serialize()` standar.

## Jika pcntl Tidak Tersedia

Jika `pcntl_fork` tidak dapat dipanggil (Windows, build PHP yang diperkeras), kumpulan worker secara otomatis beralih menjalankan setiap bagian dalam proses yang sama. Hasilnya sama seperti `-j 1`. Greph tidak menampilkan kesalahan; proses hanya berjalan dengan satu thread.

Anda dapat mendeteksi kondisi ini saat runtime dengan memeriksa `function_exists('pcntl_fork')`.

## Saran Penyetelan

- Mulailah dengan `-j` disetel ke setengah jumlah inti fisik, lalu naikkan hingga tidak ada peningkatan lagi.
- Untuk pencarian string tetap yang hanya menggunakan literal di repositori kecil, satu proses biasanya lebih cepat daripada konfigurasi paralel mana pun.
- Tidak ada tolok ukur yang dipublikasikan untuk pencarian atau penulisan ulang AST paralel. Ukur pada pohon Anda sendiri sebelum menentukan jumlah pekerjaan.
- Baris "Mode Pemindaian: Teks Paralel" pada README (`1`, `2`, dan `4` worker pada korpus WordPress) tidak mengukur kumpulan worker: baris tersebut mencari literal pendek `function`, yang ambangnya sebanyak `jobs * 4_000` file, lebih besar daripada ukuran korpus. Karena itu, semua baris berjalan dalam proses yang sama ([#8](https://github.com/inline0/greph/issues/8)).

## Batasan

- Kumpulan worker saat ini tidak mendukung pencurian pekerjaan. Jika satu bagian jauh lebih berat daripada bagian lainnya, kumpulan worker akan menunggu worker paling lambat.
- Hasil worker disangga hingga semua worker selesai. Keluaran streaming dari pemindaian yang berjalan lama (seperti saat `rg --json` melakukan streaming peristiwa) tidak didukung dalam mode paralel.
- Proses induk mengurutkan ulang hasil setelah penggabungan, jadi kumpulan worker tidak mengurangi penggunaan memori puncak dibandingkan pemindaian dengan satu proses.

Batasan ini dapat diterima untuk beban kerja yang ditargetkan Greph (pencarian kode interaktif, loop agen, tugas CI pada snapshot). Batasan ini akan ditinjau kembali jika pembuatan profil menunjukkan bahwa batasan tersebut menjadi hambatan pada korpus nyata.
