Wednesday, October 1, 2025

Saindo do inferno de dependências com o algoritmo de Tarjan

Kenny
Kenny

Imagine o seguinte: você está construindo um app há um tempo, com centenas de arquivos, módulos, classes etc. De repente, percebe que o projeto está entrando em território perigoso: o módulo Users precisa do módulo Auth para funcionar, mas, surpresa, o módulo Auth também precisa do módulo Users. É como duas pessoas tentando passar por uma porta giratória ao mesmo tempo, uma entrando e outra saindo... estamos encrencados, meu amigo.

As dependências estavam quebrando nosso código

O problema que enfrentávamos

Como em qualquer time de desenvolvimento, no Volt trabalhamos em algo bem complexo, e manter tudo bem organizado, em módulos bem definidos, é essencial.

Mas a realidade é sempre diferente da expectativa: como dependíamos de todo o núcleo do WhatsApp, dezenas de race conditions apareciam e faziam tudo quebrar aleatoriamente…

Fomos pelo caminho mais fácil:

  • Timeouts esperando os módulos carregarem em menos de 750 ms
  • Loops infinitos verificando se um módulo interno do WhatsApp existia antes de rodar nosso código
  • Lógica de retry duvidosa que, como mágica, fazia tudo funcionar

Era um desastre: confuso, pouco confiável e… cá entre nós, bem constrangedor. Eu e o pessoal passamos tempo demais brigando com esses problemas de dependência.

A descoberta do Mati

Um dia, as coisas ficaram interessantes. O Mati passou horas investigando o código minificado do WhatsApp e descobriu algo que teria nos poupado incontáveis horas e dores de cabeça.

O WhatsApp tinha encontrado um jeito muito elegante de lidar com dependências circulares e interdependências, tratando-as como grupos interconectados: o maravilhoso algoritmo de Tarjan, um algoritmo que permite identificar componentes fortemente conectados em um grafo dirigido. Internamente, com esse algoritmo, o WhatsApp conseguia carregar os módulos na ordem necessária, até parcialmente quando preciso, garantindo que todos os módulos relacionados fossem carregados. Uma verdadeira obra de arte de engenharia.

GIF

Algoritmo de Tarjan

É como analisar um grupo de amigos em que todo mundo se conhece (uns mais, outros menos). Esse algoritmo cuidava de encontrar esses grupos e tratá-los de um jeito especial conforme necessário!!!

Como trabalhamos com isso

Essa é a parte mais legal: não construímos nosso próprio sistema de gerenciamento de dependências, nem continuamos usando aquelas técnicas duvidosas para fazer as coisas funcionarem. Como praticamente trabalhamos dentro do código do WhatsApp, só precisamos usar a solução deles: vitória fácil.

Agora, cada módulo que construímos é uma beleza, e o WhatsApp cuida da parte complicada:

  • Detecta quando um módulo depende de outro (até em círculos)
  • Garante que cada módulo encontre os outros de que precisa
  • Tudo é carregado na ordem certa, sem truques

Sério, é como ter um assistente que cuida de todas as dores de cabeça que as dependências nos davam, sem timeouts e sem loops.

Por que isso mudou tudo para o time

Graças a tudo isso, criar módulos novos ficou muito fácil: usamos o mesmo sistema de injeção de dependências que o próprio time do WhatsApp usa nas funcionalidades deles, e paramos de brigar com essa arquitetura para começar a estendê-la e aproveitá-la ao máximo.

Nosso código agora é:

  • Mais limpo e mais lógico
  • Muito mais fácil para o time manter
  • Até divertido de trabalhar

Graças à descoberta do Mati, no Volt usamos literalmente a solução do WhatsApp (testada em batalha) para combater o inferno de dependências.

A maior lição

Às vezes, as melhores soluções não vêm de reinventar a roda de um jeito mais sofisticado, e sim de entender o que já funciona e construir em cima disso. O WhatsApp já tinha resolvido, com matemática pura, o problema que nos atormentou por tanto tempo. Considere este post um lembrete de que a engenharia mais elegante muitas vezes vem de dar alguns passos para trás, entender o que já existe e descobrir como tirar proveito disso.

E também de que, às vezes, as melhores descobertas vêm de um colega corajoso o bastante para mergulhar por dias em código minificado, só para concluir no fim que… aquilo que nos fazia sofrer esteve na nossa frente o tempo todo.