El escaneo de biblioteca completa que creí haber corregido
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
El escaneo de 8 segundos escondido en cada refresco
Medir en el dispositivo encontró un escaneo de la biblioteca completa corriendo en cada lote de Discover, y una trampa de medición de 16x donde la caché HTTP favorecía la ruta equivocada.
La ventana espejada mintió sobre que el teléfono estaba desbloqueado
Un arreglo de agrupación de una línea que ya estaba escrito, y tres muros entre eso y la prueba: aislamiento de actores, el alcance exclusivo a Mac de log stream, y una sesión espejada que parece desbloqueada cuando el dispositivo no lo está.
Álbumes de preestreno, y la solución que no pude verificar del todo
Los marcadores de posición 'Track N' de Apple se mostraban como si fueran datos reales. La única señal de detección que no pude confirmar se convirtió en la única señal de la que dejé de depender.