Pular para o conteúdo
Development

O scan da biblioteca inteira que eu achava que já tinha corrigido

Por Victor Da Luz
iosswiftmusickitperformancedev-logdeep-cut-atlas

Fiz uma revisão completa da base de código do Discoverer (Deep Cut Atlas) essa semana, cobrindo performance, segurança e manutenibilidade. Um dos achados doeu um pouco. Era um scan de biblioteca inteira no main actor que eu tinha certeza de já ter eliminado.

Numa passada anterior, encontrei pontos onde o app buscava todos os álbuns da biblioteca do Apple Music do usuário e fazia o scan de forma síncrona no main actor, travando a interface em bibliotecas com alguns milhares de álbuns. Corrigi aqueles. Ou foi o que pensei.

Essa revisão encontrou mais um. addAlbumToPlaylist(forTrack:), a função por trás do botão “Add album” na aba History, ainda fazia isso. Cada toque buscava a biblioteca inteira e rodava uma normalização e comparação sobre ela, ali mesmo no main actor, antes de adicionar qualquer coisa. A correção anterior nunca alcançou esse caminho de escrita porque ela vivia numa função diferente, fazendo um trabalho parecido na aparência mas distinto.

A parte irritante é que quem chamava a função já tinha a resposta. O view model por trás dessa tela mantém um conjunto barato, fora da main thread, de chaves de álbuns da biblioteca, exatamente para esse tipo de checagem. Só não estava sendo repassado adiante. A correção foi mecânica assim que enxerguei: adicionar um conjunto de chaves pré-computado como parâmetro e fazer quem chama passar o conjunto que já existe, em vez do serviço rebuscar tudo do zero.

Enquanto eu estava nisso, encontrei um segundo problema na mesma função. Adicionar as faixas de um álbum a uma playlist rodava em loop uma única chamada do MusicKit de “adicionar uma faixa” por faixa. Um álbum de 20 faixas significava 20 idas e voltas de rede sequenciais, e se o loop falhasse no meio do caminho, a playlist ficava com adição pela metade, sem rollback. O MusicKit tem uma chamada de edição em lote que substitui o conteúdo de uma playlist de uma vez só. O app já usava ela corretamente para remover faixas, só não para adicionar. Mesma API, uma direção conectada certo, a outra não.

As duas correções entraram no mesmo commit. A configuração de teste local do MusicKit só carrega quando rodando pela IDE do Xcode, não pela linha de comando, então testar significou uma passada real em dispositivo com Hang Detection ligado: tocar no botão, confirmar que não trava, depois abrir a playlist e contar as faixas para garantir que a escrita atômica não descartou nada silenciosamente.

A lição que eu continuo reaprendendo é que um padrão não se corrige de uma vez só. Ele se corrige em cada lugar onde aparece, e o sinal de que você deixou passar um não é um relatório de crash. É uma leitura lenta e completa de um código que você tinha certeza que já estava bom. Vale a pena repetir isso de vez em quando.

Leitura relacionada

Development

O scan de 8 segundos escondido em cada refresh

Medir no dispositivo encontrou um scan da biblioteca inteira rodando em cada lote do Discover - e uma armadilha de medição de 16x onde o cache HTTP favoreceu o caminho errado.

Ler
Development

A playlist que já tinha o nome certo

Um artefato de renomeação, uma API sem campo de autor pra atualizar, e um teste em dispositivo real provando que o bug já tinha se corrigido sozinho, fechado como aceitar como está.

Ler

Você também pode achar útil

AdGuard

AdGuard para iOS

Bloqueio de anúncios e rastreadores em todo o sistema no iOS, sem necessidade de um servidor DNS separado.

Como afiliado da AdGuard, ganho com compras qualificadas.

Saiba mais
Proton

Proton Mail

E-mail criptografado de ponta a ponta, com arquitetura de acesso zero.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais
Proton

Proton Pass

Gerenciador de senhas focado em privacidade, da equipe por trás do Proton Mail.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais