Problemas com Migrate_from_s3

Tenho dois pontos a abordar a seguir: o primeiro é que o limite é útil, mas atua apenas como um limite no espaço de busca; em seguida, quero poder especificar um número máximo de posts a modificar. Portanto, pretendo adicionar um número máximo de posts a modificar, além de um limite para a consulta.

Além disso, ao especificar max, faz sentido ser explícito sobre o que está sendo processado para fins de depuração. Assim, gostaria de tornar a saída verbosa se max não for nil — isso permitirá que as pessoas validem o processo antes de continuar, já que esse é o caso de uso principal deste trabalho.

Acho que vou definir max como o primeiro argumento e um limite opcional como o segundo, porque, na verdade, o max é o mais importante; o limite serve apenas para tornar o “um ping apenas” mais barato.

O segundo ponto é: não-upload, ou seja, uploads. Há pouco mais de um ano, tentei fazer upload de um vídeo no site Discourse ao qual estava me juntando, enquanto lutava para descobrir como escrever a migração do Google+ para o Discourse, e vi que o que foi escrito era https://#{SiteSettings.absolute_base_url}/original/3X/b/a/ba9e06ebc2f4397f26793bb5cd4e169308dd371d.mp4.

Hoje, ao fazer upload de um vídeo, obtenho algo como ![file_example_MP4_480_1_5MG|video](upload://caJ9ykkpshw3PFK4464VUIPWJ4l.mp4).

Pelo menos no meu teste mais recente, migrate_from_s3 estragou completamente essas URLs, fazendo com que nem sequer fossem mais URLs, o que definitivamente precisa ser corrigido. Depois, acho que, na prática, é improvável que essa tarefa encontre ![texto](url-não-upload-para-migrar). Portanto, como primeira abordagem, gostaria apenas de adicionar a sintaxe de link Markdown ao redor do protocolo mágico upload, em vez de fazer a expressão regular lidar com ambos os casos e, como resultado, ficar ainda mais difícil de ler. Mas posso mudar de ideia sobre isso.

Parece que a tag video ou audio é adicionada em JavaScript por meio de correspondência com expressão regular, então terei que copiar as expressões regulares de app/assets/javascripts/discourse/app/lib/uploads.js para a tarefa para identificá-las corretamente. Vou incluir a origem das expressões regulares para que a próxima pessoa que as encontrar saiba de onde atualizá-las. :stuck_out_tongue:

…

Esta noite, reservei um tempo para trabalhar nisso e já tenho um PR (Pull Request) em andamento. Ele não está concluído; sei que ainda há bugs nele. Não acho que tenha alterado qualquer comportamento para URLs do pseudo-protocolo upload: (normais para imagens) até agora, embora tenha adicionado uma verificação de sanidade.

Com as alterações neste PR, migrei com sucesso tanto uploads normais do pseudo-protocolo upload: quanto vídeos que atualmente são referenciados explicitamente por referência ao S3 (bem, no meu caso, espaços do Digital Ocean). Estou usando isso para modificar apenas um post por vez com este comando:

bin/rake uploads:batch_migrate_from_s3[1,1000]

Observe que isso não irá além dos primeiros 1000 posts retornados de forma um pouco aleatória pela consulta ao banco de dados; o limite baixo é apenas para agilizar a consulta enquanto migra apenas um post por vez, revisa esse post para garantir o comportamento correto e depois recomeça para encontrar outro. Este comando funciona dessa maneira apenas com o PR em que estou trabalhando atualmente!

…

Continuo a adicionar saída de diagnóstico enquanto trabalho nisso e estou começando a pensar que isso é importante além do desenvolvimento. Estou vendo muitas falhas de download transitórias nos espaços do Digital Ocean, onde alguns, mas não todos, os downloads em um post são migrados, o que, no original, apenas imprimiria um . e continuaria, dizendo Done no final, mas, na verdade, a tarefa não estaria concluída. Tive que fazer algo como cinco ou seis passes em um único post antes que todos os arquivos fossem migrados. (Não estava contando porque achei que estava depurando um bug local no início.) Estou esperando ter que executar essa migração repetidamente com o mesmo limite até que os diagnósticos estejam limpos. Portanto, estou fazendo a impressão de progresso verbosa apenas se max estiver definido, mas imprimindo mensagens de aviso úteis em qualquer caso.

No momento, estou usando a seguinte solução alternativa para os downloads intermitentemente falhos do Discourse Spaces, o que, na prática, tem melhorado tremendamente minha taxa de sucesso (3 tentativas têm sido totalmente suficientes em centenas de posts migrados até agora).

https://github.com/johnsonm/discourse/commit/7dfac12a2ea6ec04ba4e0616b4e0dbd1d806cff7

Também descobri que, de alguma forma, acabamos com vídeos maiores do que o limite que configurei quando importei do Google+ — tive que aumentar temporariamente tanto SiteSettings.max_image_size_kb quanto SiteSettings.max_attachment_size_kb enquanto fazia migrações pontuais de alguns vídeos grandes, dos quais não tenho certeza de como eles acabaram no site, mas não quero quebrá-los agora… Não faço ideia se o bug que permitia uploads grandes estava no meu script de importação, no Discourse ou apenas na minha memória sobre quais alterações fiz nas configurações ao longo do tempo. :wink:

Como grande parte do que estou migrando foi uma importação do G+, alguns dos meus posts acabaram falhando nas validações atuais. Recebi alguns erros como Unhandled failure: Validation failed: Sorry, new users can only put one image in a post e inicialmente não entendi por que eles não se repetiam. Acontece que os uploads foram movidos com sucesso para o local e todos usavam o pseudo-protocolo upload:, então o conteúdo bruto não mudou. No entanto, post.save! ainda falhou com esse erro nas validações, o que impediu que post.rebake! fosse acionado. Assim, tenho alguns posts entre 30 mil com imagens que precisam ser rebaked; infelizmente, não tenho registro de quais posts são esses. Agora mudei para post.save!(validate: false) como outra correção, então esse problema específico não deve mais ocorrer. Estou muito feliz por ter feito a migração começar a abortar em erros não tratados; caso contrário, isso potencialmente causaria muito mais danos do que apenas alguns posts.

…

Para manter meu site utilizável, incluindo o envio de notificações, enquanto executo a migração, não quero sobrecarregar as filas do Sidekiq. Sei que nomear coisas é um dos dois problemas mais difíceis da ciência da computação, junto com a invalidação de cache e erros de off-by-one, mas estou propondo DISCOURSE_MIGRATION_MAX_ENQUEUED como uma variável de ambiente para definir quantos slots de fila no total (não slots de job) podem ser preenchidos ao prosseguir para migrar outro item após um rebake durante uma migração, evitando sobrecarregar as filas, para que o site continue funcionando. Tenho um patch que adiciona isso, com valor padrão zero, para todo o rebake por post em lib/tasks/uploads.rake. Estou usando isso na minha migração de produção.

https://github.com/discourse/discourse/blob/59a761851b9c8786d3a9692f8c595372b0534f77/lib/tasks/uploads.rake

4 curtidas