Saltar al contenido
Development

El escaneo de biblioteca completa que creí haber corregido

Por Victor Da Luz
iosswiftmusickitperformancedev-logdeep-cut-atlas

Hice una revisión completa del código de Discoverer (Deep Cut Atlas) esta semana, cubriendo rendimiento, seguridad y mantenibilidad. Uno de los hallazgos dolió un poco. Era un escaneo de biblioteca completa en el main actor que estaba seguro de haber eliminado ya.

En una revisión anterior, encontré lugares donde la app traía cada álbum de la biblioteca de Apple Music de un usuario y lo escaneaba de forma sincrónica en el main actor, congelando la interfaz en bibliotecas con unos pocos miles de álbumes. Corregí esos casos. O eso creí.

Esta revisión encontró uno más. addAlbumToPlaylist(forTrack:), la función detrás del botón “Add album” de la pestaña History, todavía lo hacía. Cada toque traía la biblioteca completa y corría una normalización y comparación sobre ella, ahí mismo en el main actor, antes de agregar nada. La corrección anterior nunca llegó a esta ruta de escritura porque vivía en una función distinta que hacía un trabajo de apariencia similar pero diferente.

La parte molesta es que quien llamaba a la función ya tenía la respuesta. El view model detrás de esa pantalla mantiene un conjunto barato de claves de álbumes de biblioteca, calculado fuera del main actor, exactamente para este tipo de verificación. Simplemente no se estaba pasando hacia abajo. La corrección fue mecánica una vez que lo vi: agregar un conjunto de claves precalculado como parámetro y hacer que quien llama pase su conjunto existente en vez de que el servicio vuelva a traer todo desde cero.

Mientras estaba ahí encontré un segundo problema en la misma función. Agregar las canciones de un álbum a una lista de reproducción iteraba una sola llamada de MusicKit para “agregar una canción” por cada canción. Un álbum de 20 canciones significaba 20 viajes de red secuenciales, y si el ciclo fallaba a mitad de camino, la lista quedaba a medio agregar sin reversión. MusicKit tiene una llamada de edición por lotes que reemplaza el contenido de una lista de reproducción de una sola vez. La app ya la usaba correctamente para quitar canciones, solo que no para agregarlas. La misma API, una dirección bien conectada, la otra no.

Ambas correcciones llegaron en un solo commit. La configuración de pruebas local de MusicKit solo carga cuando se corre desde el IDE de Xcode, no desde la línea de comandos, así que probar significó una pasada real en dispositivo con Hang Detection activado: tocar el botón, confirmar que no hay congelamiento, y luego abrir la lista de reproducción y contar canciones para asegurarse de que la escritura atómica no perdió nada en silencio.

La lección que sigo reaprendiendo es que un patrón no se corrige una sola vez. Se corrige en cada lugar donde aparece, y la señal de que se pasó por alto uno no es un reporte de fallo. Es una lectura lenta y completa de código que se creía seguro que ya estaba bien. Vale la pena hacerlo de nuevo cada tanto.

Lecturas relacionadas