Parallelle workers
Greph verdeelt tekst- en AST-scans over een workerpool wanneer de hoeveelheid werk groot genoeg is om de extra overhead te rechtvaardigen. De pool is gebouwd op pcntl_fork() en valt terug op uitvoering binnen hetzelfde proces wanneer ext-pcntl niet beschikbaar is (Windows, sommige PaaS-omgevingen en hosting met beperkingen).
Parallelle scans inschakelen
Stel -j N in op CLI of jobs: N in het relevante optiesobject:
./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
use Greph\Greph;
use Greph\Text\TextSearchOptions;
Greph::searchText(
'function',
'src',
new TextSearchOptions(fixedString: true, jobs: 8),
);
Wanneer parallel verwerken begint
Greph paralleliseert niet onvoorwaardelijk. Het starten van N processen en het via pipes heen en weer sturen van hun resultaten brengt overhead met zich mee. Bij kleine bestandenlijsten weegt die overhead zwaarder dan het zoeken zelf. Daarom berekent de facade een drempel op basis van het aantal taken, de zoekmodus en de vorm van het patroon. Alleen bestandenlijsten boven die drempel worden naar de workerpool gestuurd.
De huidige heuristieken (in Greph\Greph::shouldUseTextWorkers en verwante onderdelen):
- Runs met één taak (
-j 1) worden altijd binnen hetzelfde proces uitgevoerd. - Standaardtek scans vereisen ongeveer
jobs * 2_000bestanden voordat de pool wordt ingeschakeld. - De modi tellen, bestanden met overeenkomsten en bestanden zonder overeenkomsten verlagen de drempel tot ongeveer
jobs * 750, omdat het werk per bestand goedkoper is. - Korte patronen met vaste tekenreeksen die op een identifier lijken, verhogen de drempel tot ongeveer
jobs * 4_000, omdat het letterlijke snelle pad al zo goedkoop is dat het starten van processen zelden voordeel oplevert. - AST-zoeken en AST-herschrijven gebruiken de drempel
jobs * 750.
Dit zijn heuristieken, geen garanties. Ze zijn afgestemd op het benchmarkcorpus WordPress en kunnen opnieuw worden bekeken.
Hoe de pool werkt
Greph\Parallel\WorkSplitter verdeelt de bestandenlijst over N chunks. Greph\Parallel\WorkerPool start één workerproces per chunk. Elke worker voert dezelfde closure uit op zijn deel, waarna Greph\Parallel\ResultCollector de geserialiseerde resultaten via één Unix-socketpaar per worker terugleest. Het hoofdproces wacht op alle workers en voegt de resultaten daarna samen en sorteert ze opnieuw, zodat de uitvoervolgorde stabiel blijft, ongeacht hoe het werk is verdeeld.
Voor de tekstmodus gebruikt de workerpool een aangepaste codec voor verzending over de verbinding (Greph\Text\TextResultCodec) om de geserialiseerde payload compact te houden. De AST-modus gebruikt de standaard-serialize() van PHP.
Wanneer pcntl niet beschikbaar is
Als pcntl_fork niet kan worden aangeroepen (Windows, builds met een versterkte beveiliging van PHP), valt de pool transparant terug op uitvoering van elk chunk binnen hetzelfde proces. Het resultaat is hetzelfde als bij -j 1. Greph geeft geen foutmelding; het voert alles gewoon in één thread uit.
U kunt dit tijdens runtime detecteren door function_exists('pcntl_fork') te controleren.
Tips voor afstemming
- Begin met
-jingesteld op de helft van het aantal fysieke cores en verhoog de waarde totdat u geen verbeteringen meer ziet. - Voor zoekopdrachten met alleen letterlijke vaste tekenreeksen in kleine repositories is één proces doorgaans sneller dan elke parallelle configuratie.
- Er is geen gepubliceerd benchmarkrapport voor parallel AST-zoeken of -herschrijven. Meet het op uw eigen boom voordat u een aantal taken kiest.
- De rijen 'Scanmodus: parallelle tekst' in README (
1,2en4workers op het corpus WordPress) meten de pool niet: ze zoeken naar de korte literalfunction, waarvoor de drempel vanjobs * 4_000bestanden groter is dan het corpus. Daarom wordt elke rij binnen één proces uitgevoerd (#8).
Beperkingen
- De huidige pool ondersteunt geen work-stealing. Als één chunk veel zwaarder is dan de andere, wacht de pool op de langzaamste worker.
- Workerresultaten worden gebufferd totdat alle workers klaar zijn. Parallelle modus ondersteunt geen uitvoerstream voor een langlopende scan (zoals
rg --jsongebeurtenissen streamt). - Na het samenvoegen sorteert het hoofdproces de resultaten opnieuw. Daarom vermindert de workerpool het piekgeheugenverbruik niet ten opzichte van een scan met één proces.
Deze beperkingen zijn aanvaardbaar voor de werklasten waarop Greph is gericht: interactief zoeken in code, agentloops en CI-jobs op snapshots. We bekijken ze opnieuw als profilering laat zien dat ze een knelpunt vormen bij corpora uit de praktijk.