La biblioteca JVMKit de SoundCloud proporcionaba patrones JVM compartidos —andamiaje de servicios, integración con bases de datos y Kafka, métricas— a cientos de servicios internos en Scala, Java, Clojure y JRuby. A medida que crecía la adopción, el equipo de plataforma perdió visibilidad sobre qué servicios dependían de qué partes de la API de JVMKit, lo que convertía cada versión en una apuesta: una actualización rutinaria podía romper silenciosamente servicios que el equipo ni siquiera sabía que estaban afectados.
Como las dependencias en SoundCloud se declaraban explícitamente en el archivo de compilación de cada repositorio (sbt para JVM, Gradle para Android, npm para web), el equipo indexó cada repositorio con Zoekt, un motor de búsqueda de código basado en expresiones regulares, actualizado cada cinco minutos. Una consulta simple sobre los archivos de compilación que listaban JVMKit como dependencia producía un grafo de dependencias inversas en vivo —cada servicio que se vería afectado por un cambio en JVMKit, generado automáticamente en lugar de rastreado a mano.
Con ese grafo en mano, el equipo construyó una canalización de verificación: para cada servicio dependiente, clonar el repositorio, compilarlo y probarlo sin modificaciones para establecer una línea base, luego sustituir la versión candidata de JVMKit, aplicar las correcciones por script para los cambios de API rompedores conocidos, y compilar y probar de nuevo. Si la línea base pasaba pero la candidata fallaba, la causa era el cambio en JVMKit, no una rotura preexistente en ese servicio. La comprobación se ejecutaba cada noche sobre el conjunto completo de dependientes y en cada pull request contra un subconjunto más rápido incluido en la lista de permitidos.
Compilar y probar cada consumidor antes de publicar la biblioteca
Reemplazó un proceso manual y propenso a errores (publicar, esperar a que los equipos se quejaran) por una comprobación automática y falsable que se ejecuta antes de que se publique la versión.
Ejecutar primero una línea base sin modificaciones aislaba si un fallo provenía del cambio en JVMKit o de un servicio que ya estaba roto ese día.
Dividir la verificación en una ejecución completa nocturna y una ejecución rápida limitada a las PR mantuvo la retroalimentación ágil sin omitir la cobertura completa.
El grafo de dependencias inversas se generaba a partir del código, no se mantenía a mano, por lo que se mantenía preciso a medida que se añadían o eliminaban servicios.
Cuando una biblioteca interna sostiene cientos de servicios, no la publiques con la esperanza de que salga bien: haz que el grafo de dependencias sea consultable y deja que CI pruebe primero cada consumidor aguas abajo.
JVMKit siguió impulsando cientos de servicios y miles de instancias en producción en SoundCloud. Con la canalización de verificación en marcha, el equipo de plataforma informó que publicaba JVMKit con más frecuencia, con fallos atribuibles a un paso específico y a una causa específica en lugar de manifestarse como roturas inexplicables aguas abajo.
CONSULTA LAS PRUEBAS
Las fuentes
- Did I Break You? Reverse Dependency Verification SoundCloud Engineering · developers.soundcloud.com ·