Até se tornar o Dune, um sistema de build melhor para OCaml
(blog.janestreet.com)- A Jane Street, insatisfeita com o OMake, criou o Jenga, mas a adoção externa foi fraca; o Jbuilder, feito para compatibilidade, acabou crescendo de forma inesperada como ferramenta fundamental da comunidade OCaml
- O apelo inicial do Jbuilder não eram os recursos, mas sim a velocidade e a portabilidade; em projetos da Jane Street, ele levou à adoção ao compilar cerca de 5 vezes mais rápido que o OCamlbuild
- Em colaboração com a OCaml Labs, o Jbuilder evoluiu para um sistema de build completo e, após discussão na comunidade por causa de conflito de nome com o antigo IDE Java da Borland, passou a se chamar Dune
- A Jane Street manteve Jenga e Dune em paralelo por um tempo, mas, com a base de código crescendo para 65M de linhas de OCaml e 5M de linhas de Python, a dificuldade da migração interna aumentou muito
- Depois de mais de um ano de trabalho intensivo, a base de código da Jane Street agora é compilada com Dune, e builds com o cache quase todo preenchido ficaram 2 a 3 vezes mais rápidos
O Jenga nasceu da insatisfação com o OMake
- Um sistema de build é a ferramenta do dia a dia do desenvolvedor que cria programas executáveis a partir de vários arquivos-fonte, além de cuidar da invocação do compilador e da execução de testes
- Por volta de 2012, a Jane Street ficou insatisfeita com o OMake, então um dos sistemas de build padrão do OCaml, e criou seu próprio sistema de build, o Jenga
- Como o Jenga funcionava bem internamente, a Jane Street decidiu torná-lo público, acreditando que a comunidade também poderia usá-lo com proveito
- Esperava que usuários externos experimentassem o Jenga e contribuíssem com ele
- Também acreditava que isso facilitaria a abertura do código de seus projetos como open source
- Na prática, a adoção externa ficou abaixo do esperado
- Ele não funcionava no Windows
- Para adotar o Jenga, na prática era preciso aceitar todo o jeito Jane Street de compilar OCaml
- Como o uso externo não cresceu, a Jane Street voltou a fechar o Jenga, e o problema de compilar seu código open source permaneceu
O Jbuilder foi criado como uma camada de compatibilidade
- Em 2016, a Jane Street decidiu criar o Jbuilder, uma ferramenta simples e multiplataforma que permitiria a usuários externos compilar seu código sem precisar adotar o Jenga por completo
- A ideia também era reduzir o peso de reescrever builds para se adequar ao OCamlbuild, que na época surgia como novo padrão para builds de projetos OCaml
- O Jbuilder entendia os arquivos
jbuildusados pelo Jenga para configuração de build e executava os comandos de compilação necessários em ordem topológica - O Jbuilder inicial estava longe de ser um sistema de build no sentido convencional
- Ele não selecionava e reexecutava apenas os comandos cujas entradas haviam mudado
- Em vez disso, reexecutava todos os comandos a cada vez
Como o Jbuilder virou Dune
- O Jbuilder foi pensado originalmente como uma pequena camada de compatibilidade, mas os usuários começaram a usá-lo também para compilar seus próprios projetos, além dos pacotes da Jane Street
- O principal fator por trás da adoção foi a velocidade
- Na compilação de projetos da Jane Street, era cerca de 5 vezes mais rápido que o OCamlbuild
- Tinha boa portabilidade
- Sua estrutura simples facilitava modificações
- A Jane Street começou a colaborar com a OCaml Labs, hoje Tarides, para transformar o Jbuilder em um sistema de build mais completo
- O nome também virou um problema à parte
- Já existia o JBuilder, IDE Java da Borland
- Embora esse sistema já tivesse praticamente desaparecido há muito tempo, mesmo consultando o detentor dos direitos sobre a intenção de usar o nome, não foi possível obter permissão
- Após discussões na comunidade, o novo nome escolhido foi Dune
- A discussão relacionada ocorreu no tópico de proposta de novo nome para o Jbuilder
O custo de manter dois sistemas de build ao mesmo tempo
- Com a popularidade do Dune crescendo, a Jane Street passou a manter e dar suporte simultaneamente a dois sistemas de build completos criados por ela: Jenga e Dune
- O Dune se consolidou como um sistema com arquitetura redesenhada, desempenho rápido na maioria dos builds dos usuários, adoção mais ampla, além de APIs e experiência de uso melhores
- A questão de quando migrar o ambiente interno para o Dune surgiu naturalmente, mas a equipe de build systems já estava ocupada apenas acompanhando o crescimento da base de código
- Quando o Dune começou, em 2016, o código em OCaml tinha 4M de linhas
- Hoje há 65M de linhas de OCaml e 5M de linhas de Python
- A migração para o Dune era pesada demais para ser iniciada de verdade, e só se repetiam estimativas otimistas de que “talvez fosse possível nos próximos 6 a 12 meses”
- No ano passado, a Jane Street ampliou a equipe de build systems para 5 engenheiros em tempo integral e então iniciou o trabalho de migração que vinha sendo adiado havia muito tempo
O Dune substituiu o Jenga dentro da Jane Street
- Um dos maiores trabalhos foi fazer o Dune escalar para atender à gigantesca base de código da Jane Street
- Um dos motivos de o Dune ser rápido externamente era que a maioria dos usuários compilava projetos muito menores que o repositório de 70M de linhas da Jane Street
- O Jenga também não ficou parado no tempo por 10 anos
- A Jane Street continuou melhorando a implementação do Jenga para acompanhar o crescimento da base de código
- O Jenga já estava bastante otimizado para as exigências de um monorepo em larga escala
- Boa parte desse trabalho de otimização precisou ser levada para o Dune
- O trabalho de integração do dia a dia também não foi trivial
- O sistema de build é chamado por vários fluxos de trabalho
- Os três editores, Vim, Emacs e VSCode, tinham integrações customizadas para o Jenga
- Foi preciso migrar cada integração, uma por uma, para o Dune
- Após mais de um ano de trabalho intensivo, a base de código da Jane Street agora é compilada com Dune
- No momento da transição, o desempenho do Dune em geral era igual ou melhor que o do Jenga
- Em alguns casos, o desempenho foi muito superior
- Quando a maior parte do trabalho de build já está em cache, os builds ficam 2 a 3 vezes mais rápidos
Próximas melhorias possíveis sobre um sistema único
- A Jane Street pretende publicar como open source boa parte do trabalho de melhoria de desempenho do Dune, e parte disso já foi aberta
- A empresa está tomando cuidado para refletir as mudanças possíveis no upstream, para não acabar novamente com dois sistemas: um fork do Dune para a Jane Street e outro Dune externo
- O Dune passou a ser uma base mais adequada para criar novos recursos
- A base de código é mais simples e mais fácil de trabalhar
- Agora é possível concentrar esforços em um único sistema
- Os recursos seguintes também ficaram mais próximos
-
Build distribuído
- Builds rasos, isto é, “builds without the bytes”
- Carregamento em cache do próprio grafo de build
- A equipe de build systems cresceu para 12 engenheiros em tempo integral em Nova York, Londres e Singapura, e o ritmo de melhorias no Dune também aumentou
-
1 comentários
Comentários do Hacker News
Mensagem de crash do Dune:
https://github.com/ocaml/dune/issues/2767
O podcast técnico Signals and Threads, da Jane Street, teve um episódio sobre sistemas de build em 2020, e recomendo muito
Os outros episódios também são bons; recomendo especialmente The Future of Programming, com Richard Eisenberg, e What is an Operating System?, com Anil Madhavapeddy
¥https://signalsandthreads.com/build-systems/
°https://signalsandthreads.com/future-of-programming/
§https://signalsandthreads.com/what-is-an-operating-system/
https://signalsandthreads.com/multicast-and-the-markets/
É respeitável que a Jane Street tenha provado que programação funcional com tipos HM também pode estar pronta para produção e ser muito rápida se receber esforço suficiente
Ainda ouço de vez em quando que linguagens funcionais de estilo mais acadêmico não podem ser usadas em produção, mas OCaml mostra que isso é perfeitamente possível mesmo com requisitos de alto desempenho
https://mercury.com/
É uma ótima opção para criar programas de alta qualidade enquanto interopera amplamente com sistemas existentes
Segundo um post de blog de alguns anos atrás, eles também chegaram a mexer com Roc, mas não sei se usam hoje
[0] https://blog.noredink.com
Sempre que vejo posts no blog da Janestreet, acabo rindo por dentro ao pensar que trabalhar na Jane, no setor financeiro, parece mais divertido e mais bem remunerado do que 90% dos chamados empregos na indústria de tecnologia
Em tecnologia no mercado financeiro, há muito mais trabalhos que não são tão interessantes nem tão bem pagos quanto uma empresa média de tecnologia, muito menos a Jane Street
Muito do trabalho no mercado financeiro é corrigir código Java de 20 anos ou encontrar novas maneiras de colocar e tirar dados de arquivos Excel para relatórios personalizados
E ouvi dizer que entrar na JS é muito mais difícil do que no Google/Meta
Eu também me candidatei no passado, e o entrevistador foi bem desagradável; nunca passei por isso em entrevistas de big tech, então não fiquei com uma boa impressão
Ainda assim, coloco acima de trabalhar para fazer as pessoas clicarem em anúncios
Como em outras empresas, há uma mistura de projetos interessantes e trabalho entediante
A única coisa pior do que uma base de código complexa é um sistema de build complexo. CMake é repugnante
É do tipo: “Para compilar esta linguagem, aprenda outra linguagem nova!”
Ele também faz algumas coisas direito, e parte do que faz errado é administrável
Se eu puder obter procedimentos de build multiplataforma a partir de um conjunto de arquivos de configuração editáveis por humanos, aceito certo grau de sofrimento
A linguagem de script horrível atrapalha, mas poderia melhorar se houvesse motivação suficiente
Há algum tempo, depois de Lisp, passei alguns anos no lado do Haskell como minha primeira experiência funcional
OCaml não me dizia muito, e eu tinha uma forma rara de alergia a ponto e vírgula, então Haskell me parecia muito mais bonito
Mas recentemente experimentei Reason, achei muito bom, e de repente tudo relacionado a OCaml ficou interessante
https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...
https://ocaml.org/docs/toplevel-introduction#loading-librari...
https://reasonml.github.io/ parece legal, como um OCaml com cara de JavaScript
Acho que, depois que você percebe essa linha, fica tudo bem, mas parece que é preciso aprender a pensar nessa estrutura, como em Lisp. Ainda assim, uma tela cheia de código Haskell me assusta
Entre eles, SML/NJ foi o mais fácil de ler
Fico curioso se alguém já usou as bibliotecas e ferramentas OCaml open source da Jane Street em um projeto minimamente sério
Pela impressão que tive ao dar uma olhada rápida, eles investiram bastante em criar um ecossistema e abrir o código, mas não parecia algo “pronto” para ser usado por pessoas fora da Jane Street
Para encontrar algo, você precisa ser bastante hábil em ler assinaturas de funções, mas fora isso não tenho reclamações. Por exemplo, as funções para converter todos os tipos básicos para s-expressions e de volta, se você souber que existem e planejar com antecedência, economizam uma quantidade enorme de tempo
Também usei outras bibliotecas; os ppx de logging e teste unitário são praticamente padrão no mundo OCaml, se é que isso é possível. Também usei o formatador de código, um framework de testes e uma implementação de estruturas de dados avançadas
Às vezes, como em outro comentário, encontro algo que simplesmente não funciona. Coisas como depender de algo não documentado distribuído separadamente ou precisar de uma configuração secreta. Não é má-fé; muitas vezes, se você abre uma issue e volta um ou dois anos depois, funciona
Não é que não haja frustração nenhuma, mas eu aprecio a abordagem de abrir tudo em vez de gastar recursos testando e refinando menos releases. A qualidade do código em geral é muito alta e, mesmo que eu não consiga fazê-lo rodar, ele serve como uma implementação de exemplo rigorosa e verificada
Acho a API muito melhor que a stdlib padrão
Gosto do Lean 4, mas não é fácil receber ajuda de IA. O trabalho de hoje em andamento é digerir o manual de referência para que caiba bem em uma janela de contexto de 200K. Vou ver se ajuda
É bem surpreendente que desenvolver um novo sistema de build próprio e migrar para ele ainda faça sentido, em vez de adotar uma ferramenta pronta como buck2 ou bazel
Não estou dizendo que introduzir essas ferramentas de build avançadas seja fácil, mas como isso se compara a fazer uma do zero? Fico curioso se há algo especial que torna o dune muito diferente
O primeiro release do Bazel foi em 2015, e o Buck é de 2013
A JS tem um pouco de cultura NIH, mas não sei se isso pesou aqui. Na época não havia muitas boas ferramentas de build, especialmente para uma empresa com uma stack tecnológica pouco convencional
Em especial, pelo que sei, é preciso conseguir executar o ocamldep antes, ou compilar duas vezes; o buck2 consegue fazer isso, enquanto o Bazel, se não me falha a memória, exige gambiarras
Os dois são mais ou menos parecidos. Na velocidade pura de chamar as ferramentas de build do OCaml, o dune é rápido; quando é preciso recompilar muita coisa e usar um sistema de build distribuído, o buck2 ganha
A grande dor é a integração com LSP. Como a única forma de o servidor LSP conhecer as dependências de um arquivo é por meio do build, ele precisa ficar fortemente acoplado ao sistema de build. No dune, tudo é fornecido de forma limpa. Com buck2, também amarramos as coisas de algum jeito, mas não fica tão bom
Dune é de longe o melhor nome para um sistema de build, e nada chega perto
Começar tentando criar um sistema de build melhor e então “por acaso” criar um sistema de build melhor... é bem estranho o jeito como esses acasos acontecem