A biblioteca JVMKit da SoundCloud fornecia padrões JVM compartilhados — scaffolding de serviços, integração com banco de dados e Kafka, métricas — para centenas de serviços internos em Scala, Java, Clojure e JRuby. À medida que a adoção crescia, a equipe de plataforma perdeu visibilidade sobre quais serviços dependiam de quais partes da API do JVMKit, tornando cada versão uma aposta: uma atualização de rotina podia quebrar silenciosamente serviços que a equipe nem sabia estarem afetados.

Como as dependências na SoundCloud eram declaradas explicitamente no arquivo de build de cada repositório (sbt para JVM, Gradle para Android, npm para web), a equipe indexou todos os repositórios com o Zoekt, um mecanismo de busca de código baseado em regex, atualizado a cada cinco minutos. Uma consulta simples aos arquivos de build que listavam o JVMKit como dependência produzia um grafo de dependências reverso ao vivo — todos os serviços que seriam afetados por uma mudança no JVMKit, gerado automaticamente em vez de rastreado manualmente.

Com esse grafo em mãos, a equipe construiu um pipeline de verificação: para cada serviço dependente, clonar o repositório, compilar e testá-lo sem modificações para estabelecer uma linha de base, depois substituir pela versão candidata do JVMKit, aplicar quaisquer correções por script para mudanças de API quebradas conhecidas, e compilar e testar novamente. Se a linha de base passasse mas a candidata falhasse, a mudança no JVMKit era a causa, não uma quebra pré-existente naquele serviço. A verificação rodava todas as noites sobre o conjunto completo de dependentes e em cada pull request contra um subconjunto mais rápido, em lista de permissões.

Compilar e testar cada chamador antes de lançar a biblioteca

Substituiu um processo manual e propenso a erros (lançar, esperar as equipes reclamarem) por uma verificação automática e falseável que roda antes do lançamento ser enviado.

Rodar primeiro uma linha de base sem modificações isolava se uma falha vinha da mudança no JVMKit ou de um serviço que já estava quebrado naquele dia.

Dividir a verificação em uma execução completa noturna e uma execução rápida limitada a PRs mantinha o feedback ágil sem pular a cobertura completa.

O grafo de dependências reverso era gerado a partir do código, não mantido manualmente, então permanecia preciso à medida que serviços eram adicionados ou removidos.

Quando uma biblioteca interna sustenta centenas de serviços, não lance na esperança — torne o grafo de dependências consultável e deixe a CI testar cada chamador a jusante primeiro.

O JVMKit continuou a sustentar centenas de serviços e milhares de instâncias em produção na SoundCloud. Com o pipeline de verificação em vigor, a equipe de plataforma relatou lançar o JVMKit com mais frequência, com falhas rastreáveis a um passo específico e a uma causa específica, em vez de surgirem como quebras inexplicadas a jusante.

CONFIRA AS EVIDÊNCIAS

As fontes

  1. Did I Break You? Reverse Dependency Verification SoundCloud Engineering · developers.soundcloud.com ·