
# Párhuzamos feldolgozók

A Greph szöveges és AST-pásztázásokat oszt szét egy feldolgozócsoporton, ha a munka mérete indokolja a többletterhelést. A csoport az `pcntl_fork()` alapjaira épül, és folyamaton belüli végrehajtásra vált vissza, ha a `ext-pcntl` nem érhető el (Windows, egyes PaaS-környezetek, korlátozott tárhelyszolgáltatás).

## Párhuzamos pásztázások engedélyezése

Állítsa be az `-j N` értékét a CLI helyen, vagy az `jobs: N` értékét a megfelelő beállításobjektumban:

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

## Mikor indul el a párhuzamosítás

A Greph nem párhuzamosít feltétel nélkül. N folyamat elindítása és az eredmények csöveken keresztüli visszaküldése többletterheléssel jár, amely kis fájllistáknál meghaladhatja magának a keresésnek a költségét. Ehelyett a homlokzat a feladatszám, a keresési mód és a minta alakja alapján küszöbértéket számít. Csak a küszöböt meghaladó fájllisták kerülnek a feldolgozócsoporthoz.

A jelenlegi heurisztikák (az `Greph\Greph::shouldUseTextWorkers` fájlban és a kapcsolódó helyeken):

- Az egyfeladatos futások (`-j 1`) mindig folyamaton belül futnak.
- Az alapértelmezett szöveges pásztázásoknál nagyjából `jobs * 2_000` fájl szükséges a csoport elindításához.
- A darabszám-, egyezést tartalmazó fájlokat és egyezést nem tartalmazó fájlokat kereső módoknál a küszöb nagyjából `jobs * 750` fájlra csökken, mert a fájlonkénti feldolgozás olcsóbb.
- A rövid, azonosítószerű, rögzített karakterlánc-mintáknál a küszöb nagyjából `jobs * 4_000` fájlra emelkedik, mert a szó szerinti gyors útvonal már eleve olyan olcsó, hogy az elágaztatás ritkán éri meg.
- Az AST-keresés és -átírás ugyanazt a `jobs * 750` küszöböt használja.

Ezek heurisztikák, nem ígéretek. A WordPress mérési adathalmaz alapján vannak beállítva, és később módosulhatnak.

## A feldolgozócsoport működése

A `Greph\Parallel\WorkSplitter` N részre osztja a fájllistát. Az `Greph\Parallel\WorkerPool` minden részhez elindít egy feldolgozó folyamatot, amely ugyanazt a lezáró függvényt futtatja a saját szeletén, az `Greph\Parallel\ResultCollector` pedig dolgozónként egy Unix aljzaton keresztül olvassa vissza a sorosított eredményeket. A szülőfolyamat megvárja az összes feldolgozót, majd egyesíti és újrarendezi az eredményeket, így a kimenet sorrendje a feladat felosztásától függetlenül stabil marad.

Szöveges módban a feldolgozócsoport egy egyedi, vezetékes protokollhoz készült kódolót (`Greph\Text\TextResultCodec`) használ a sorosított adatok tömören tartásához. Az AST-mód az PHP szabványos `serialize()` formátumát használja.

## Ha a pcntl nem érhető el

Ha az `pcntl_fork` nem hívható meg (Windows, megerősített PHP build), a csoport észrevétlenül visszavált arra, hogy minden részt folyamaton belül futtasson. Az eredmény ugyanaz, mint az `-j 1` esetében. A Greph nem jelez hibát; egyszerűen egyetlen szálon fut.

Ezt futás közben az `function_exists('pcntl_fork')` ellenőrzésével állapíthatja meg.

## Hangolási tanácsok

- Kezdje úgy, hogy az `-j` értékét a fizikai magok számának felére állítja, majd növelje, amíg javulást tapasztal.
- Kizárólag szó szerinti, rögzített karakterláncos keresésnél kis tárolókban az egyfolyamatos futás általában gyorsabb bármely párhuzamos beállításnál.
- Egyetlen közzétett mérés sem vizsgálja a párhuzamos AST-keresést vagy -átírást. A feladatszám beállítása előtt mérje meg saját fájlfáján.
- A README „Pásztázási mód: párhuzamos szöveg” sorai (`1`, `2` és `4` feldolgozóval a WordPress adathalmazon) nem mérik a feldolgozócsoportot: a rövid `function` szó szerinti karakterláncra keresnek, amelynél a `jobs * 4_000` fájlos küszöb nagyobb az adathalmaz méreténél, ezért minden sor folyamaton belül fut ([#8](https://github.com/inline0/greph/issues/8)).

## Korlátozások

- A jelenlegi csoport nem támogatja a munkalopást. Ha az egyik rész sokkal nagyobb terhelést jelent, mint a többi, a csoport megvárja a leglassabb feldolgozót.
- A feldolgozók eredményei pufferelve maradnak, amíg minden feldolgozó be nem fejezi a munkát. A hosszú pásztázás kimenetének folyamatos továbbítása (ahogyan a `rg --json` eseményeket továbbít) párhuzamos módban nem támogatott.
- Az egyesítés után a szülőfolyamat újrarendezi az eredményeket, így a feldolgozócsoport nem csökkenti a csúcsmemória-használatot az egyfolyamatos pásztázáshoz képest.

Ezek a korlátozások elfogadhatók azokhoz a munkaterhelésekhez, amelyeket a Greph céloz (interaktív kódkeresés, ügynökciklusok, pillanatképeken futó CI-feladatok). Újraértékeljük őket, ha a profilozás valós adathalmazokon szűk keresztmetszetet mutat.
