Workers paralelos
Greph distribui as varreduras de texto e AST por um conjunto de workers quando o volume de trabalho justifica a sobrecarga. O conjunto usa pcntl_fork() e recorre à execução no próprio processo quando ext-pcntl não está disponível (Windows, alguns ambientes PaaS, hospedagem restrita).
Ativar varreduras paralelas
Defina -j N em CLI ou jobs: N no objeto de opções relevante:
./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),
);
Quando o paralelismo é ativado
Greph não paraleliza incondicionalmente. Criar N processos e transferir os resultados deles por pipes gera sobrecarga que, em listas pequenas de arquivos, supera o custo da própria pesquisa. Em vez disso, a fachada calcula um limite com base no número de tarefas, no modo de pesquisa e no formato do padrão. Somente listas de arquivos acima do limite são distribuídas ao conjunto de workers.
As heurísticas atuais (em Greph\Greph::shouldUseTextWorkers e similares):
- Execuções com uma tarefa (
-j 1) sempre ocorrem no próprio processo. - Varreduras de texto padrão exigem cerca de
jobs * 2_000arquivos para ativar o conjunto. - Os modos de contagem, arquivos com correspondências e arquivos sem correspondências reduzem o limite para cerca de
jobs * 750, pois o trabalho por arquivo é mais barato. - Padrões curtos de cadeia fixa em formato de identificador aumentam o limite para cerca de
jobs * 4_000, pois o caminho rápido literal já é tão barato que raramente compensa criar processos. - A pesquisa e a reescrita de AST usam o limite
jobs * 750.
Esses números são heurísticas, não garantias. São ajustados com base no conjunto de benchmarks WordPress e podem ser revistos.
Como o conjunto funciona
Greph\Parallel\WorkSplitter distribui a lista de arquivos em N partes. Greph\Parallel\WorkerPool cria um processo worker por parte; cada worker executa o mesmo closure na sua fatia; e Greph\Parallel\ResultCollector lê os resultados serializados por um par de sockets Unix para cada worker. O processo pai aguarda todos os workers e, em seguida, combina e reordena os resultados para manter a ordem da saída estável, independentemente de como o trabalho foi dividido.
No modo de texto, o conjunto de workers usa um codec personalizado para transmissão (Greph\Text\TextResultCodec) para manter compacto o conteúdo serializado. O modo AST usa o serialize() padrão de PHP.
Quando pcntl não está disponível
Se pcntl_fork não puder ser chamado (Windows, compilações PHP reforçadas), o conjunto recorre de forma transparente à execução de cada parte no próprio processo. O resultado é o mesmo que em -j 1. Greph não gera erro; simplesmente executa em uma única thread.
Você pode detectar isso em tempo de execução verificando function_exists('pcntl_fork').
Recomendações de ajuste
- Comece com
-jdefinido como metade do número de núcleos físicos e aumente até deixar de ver melhorias. - Para pesquisas somente literais por cadeia fixa em repositórios pequenos, um único processo costuma ser mais rápido do que qualquer configuração paralela.
- Nenhum benchmark publicado mede a pesquisa ou reescrita paralela de AST. Faça medições na sua própria árvore antes de definir o número de tarefas.
- As linhas "Modo de varredura: texto paralelo" do README (
1,2e4workers no conjunto WordPress) não medem o conjunto de workers: elas pesquisam o literal curtofunction, cujo limite dejobs * 4_000arquivos supera o tamanho do conjunto. Por isso, todas as linhas são executadas no próprio processo (#8).
Limitações
- O conjunto atual não oferece roubo de tarefas. Se uma parte for muito mais pesada que as demais, o conjunto aguardará o worker mais lento.
- Os resultados dos workers ficam em buffer até que todos terminem. A saída em fluxo de uma varredura longa (como os eventos transmitidos por
rg --json) não é compatível com o modo paralelo. - O processo pai reordena os resultados depois de combiná-los, portanto o conjunto de workers não reduz o pico de uso de memória em comparação com uma varredura em processo único.
Essas limitações são aceitáveis para as cargas de trabalho visadas por Greph (pesquisa interativa de código, ciclos dos agentes, tarefas de CI em snapshots). Serão revistas se a criação de perfis mostrar que são um gargalo em conjuntos de dados reais.