Nesta página, descrevemos como otimizar o desempenho da compilação do Bazel ao executar o Bazel repetidamente.
Estado do tempo de execução do Bazel
Uma invocação do Bazel envolve várias partes interativas.
A interface de linha de comando (CLI)
bazel
é a ferramenta de front-end voltada para o usuário e recebe comandos do usuário.A ferramenta da CLI inicia um servidor do Bazel para cada base de saída distinta. O servidor do Bazel geralmente é persistente, mas será encerrado após algum tempo de inatividade para não desperdiçar recursos.
O servidor do Bazel executa as etapas de carregamento e análise de um determinado comando (
build
,run
,cquery
etc.), em que constrói as partes necessárias do gráfico de versão na memória. As estruturas de dados resultantes são mantidas no servidor do Bazel como parte do cache de análise.O servidor do Bazel também pode executar a ação ou enviar ações para execução remota, se estiver configurado para isso. Os resultados das execuções da ação também são armazenados em cache, ou seja, no cache de ação (ou cache de execução, que pode ser local ou remoto, e pode ser compartilhado entre servidores do Bazel).
O resultado da invocação do Bazel é disponibilizado na árvore de saída.
Como executar o Bazel iterativamente
Em um fluxo de trabalho típico do desenvolvedor, é comum criar (ou executar) um trecho de código repetidamente, geralmente em uma frequência muito alta (por exemplo, para resolver algum erro de compilação ou investigar um teste com falha). Nessa situação, é importante que
invocações repetidas de bazel
tenham a menor sobrecarga possível em relação à
ação repetida e subjacente (por exemplo, invocar um compilador ou executar um teste).
Com isso em mente, vamos analisar novamente o estado do ambiente de execução do Bazel:
O cache de análise é uma parte essencial dos dados. Uma quantidade significativa de tempo pode ser gasta apenas nas fases de carregamento e análise de uma execução a frio (ou seja, uma execução logo após o servidor do Bazel ser iniciado ou quando o cache de análise for descartado). Para uma versão fria única e bem-sucedida (por exemplo, para uma versão de produção), esse custo é possível, mas, para criar repetidamente o mesmo destino, é importante que esse custo seja amortizado e não repetido a cada invocação.
O cache de análise é bastante volátil. Primeiro, ele faz parte do estado em processo do servidor do Bazel. Por isso, perder o servidor perderá o cache. Mas o cache também é invalidado com muita facilidade: por exemplo, muitas sinalizações de linha de comando bazel
fazem com que o cache seja descartado. Isso ocorre porque muitas sinalizações afetam o gráfico da versão (por exemplo, devido a atributos configuráveis). Algumas alterações de sinalização também podem fazer com que o servidor Bazel seja reiniciado (por exemplo, alterando opções de inicialização).
Um bom cache de execução também é importante para o desempenho do build. Um cache de execução pode ser mantido localmente no disco ou remotamente. O cache pode ser compartilhado entre servidores do Bazel e, de fato, entre desenvolvedores.
Evite descartar o cache de análise
O Bazel imprimirá um aviso se o cache de análise for descartado ou o servidor for reiniciado. É preciso evitar uma destas opções durante o uso iterativo:
Fique atento para alterar as sinalizações
bazel
no meio de um fluxo de trabalho iterativo. Por exemplo, misturar umbazel build -c opt
com umbazel cquery
faz com que cada comando descarte o cache de análise do outro. Em geral, tente usar um conjunto fixo de sinalizações durante todo o fluxo de trabalho.A perda do servidor do Bazel perde o cache de análise. O servidor do Bazel tem um tempo ocioso configurável, após o qual é encerrado. Você pode configurar esse tempo por meio do arquivo Bazelrc para atender às suas necessidades. O servidor também é reiniciado quando as sinalizações de inicialização são alteradas. Portanto, evite alterá-las, se possível.
Cuidado se o servidor do Bazel for eliminado se você pressionar Ctrl-C repetidamente enquanto o Bazel estiver em execução. É tentador tentar economizar tempo interrompendo uma versão em execução que não é mais necessária, mas pressione Ctrl+C apenas uma vez para solicitar uma finalização normal da invocação atual.
Se você quiser usar vários conjuntos de sinalizações do mesmo espaço de trabalho, use várias bases de saída distintas, alternadas com a sinalização
--output_base
. Cada base de saída recebe o próprio servidor do Bazel.