Como posso recuperar avatares ausentes?

Tivemos um problema semelhante a este #bug:

https://meta.discourse.org/t/missing-user-profile-pictures/93844

Existe alguma maneira de recuperar os avatares ausentes?

P.S.: Tentei usar este guia e executei rake avatars:refresh, mas nada aconteceu.

Esse problema é como um vírus e está se espalhando para mais avatares! Uma observação estranha foi esta:

no Firefox alguns avatares são exibidos, enquanto estão ausentes no Chrome. Isso não significa que no Firefox nenhum avatar esteja faltando. Há avatares faltando no Firefox também!

Captura de tela do Firefox

Captura de tela do Chrome

Esse bug realmente foi corrigido?

Também encontrei o mesmo problema e estou investigando-o no momento. No caso que estou analisando, ele está relacionado ao armazenamento externo.

@Pad_Pors, você ainda está enfrentando esse problema? Além disso, você já fez ou tem uploads armazenados no S3?

Bom saber que um especialista está investigando isso :ok_hand:

Sim, ainda estamos enfrentando esse problema e, sim, costumávamos ter uploads armazenados no S3, mas não mais.

O mesmo para nós, @angus. Temos o S3. Avise-nos se precisar de logs ou qualquer outra coisa. Muito obrigado.

No caso que estou analisando, as imagens de avatar ausentes foram movidas para a pasta tombstone no S3 após uma atualização via linha de comando e uma atualização manual do PostgreSQL da versão 10 para a 12. Ainda não tenho certeza do motivo exato.

Localizando os uploads

@Jeremie_Leroy @Pad_Pors Se quiserem verificar se o mesmo ocorre no seu caso, a maneira como verifiquei os avatares ausentes na minha pasta tombstone do S3 foi a seguinte:

  1. Obtive o SHA1 (a string de 16 caracteres na URL de upload) de um upload de avatar que sabia estar corrompido após a migração. Fiz isso pegando o ID de upload da URL do avatar corrompido (é a primeira parte do nome do arquivo, por exemplo, para 6254_2.png o ID é 6254) e, em seguida, usando esse ID para procurar o SHA1 do upload em um dump recente do banco de dados. Se você não se sentir confortável com a linha de comando, pode visualizar seus dados em um dump usando uma interface gráfica do PostgreSQL como Postico 2.

  2. Realizei uma busca pelo SHA1 na pasta tombstone do bucket S3 relevante usando a AWS CLI.

    aws s3api list-objects --bucket <bucket_name> --query "Contents[?contains(Key, <sha1>)]" --prefix "tombstone"
    

    (você precisa alterar <bucket_name> e <sha1>)

Se funcionar, você receberá uma lista de resultados semelhante a esta:

{
  "Key": "tombstone/original/2X/d/d7b553ff276fca054c7090e859ef5339fd1f936e.jpg",
  "LastModified": "2020-05-16T11:45:03+00:00",
  "ETag": ## string de letras e números,
  "Size": 64580,
  "StorageClass": "STANDARD",
  "Owner": {
     "ID": ## string de letras e números
   }
}

Note que 16/05 foi quando realizei a atualização. Todos os avatares tombstonados incorretamente têm carimbos de data/hora de aproximadamente aquela época. Suspeito que o problema levou algum tempo para aparecer em produção e o fez de forma intermitente, devido ao cache.

Recuperação

Pelo que entendo, UploadRecovery (e sua tarefa rake associada) é específica para uploads de posts e não lida com avatares tombstonados.

Atualmente, estou analisando a adição (patch) de um novo método ao UploadRecovery que utiliza recover_from_s3 para recuperar os uploads de avatares.

Se alguém souber de uma maneira mais fácil de recuperar avatares tombstonados incorretamente no S3, estou ouvindo.

@tgxworld alguma ideia?

Isso é complicado para mim. Existem outras pessoas na mesma situação? Vale a pena trabalhar em uma atualização? @sam @codinghorror

Obrigado, @angus, por compartilhar o caminho de verificação, mas não estamos mais usando AWS nem S3. Na verdade, se não me engano, o problema começou após migrarmos da AWS.

Ficaria feliz se o problema estivesse sendo resolvido, mas, no momento, é muito mais fácil pedir para esses poucos usuários reenviarem seus avatares e torcer para que o problema não se espalhe para novos usuários!

Resolvi isso com sucesso no site que estou gerenciando, usando uma versão adaptada da mesma lógica que recupera imagens tombstonadas incorretamente em posts: discourse/lib/upload_recovery.rb at main · discourse/discourse · GitHub.

@Jeremie_Leroy Parte do motivo pelo qual postei os passos acima é que existem várias causas possíveis para avatares ausentes. Para saber se isso funcionará para você, primeiro você precisa confirmar que há avatares tombstonados incorretamente, ou seja, qual é a causa do problema no seu caso.

Também entendo que realizar essa análise é muito difícil se você não estiver familiarizado com os aspectos técnicos do Discourse. Coloquei a solução que usei em um plugin que você pode testar no seu próprio site. Veja as instruções abaixo.

@Pad_Pors Se você estiver disposto a apenas pedir às pessoas que reenviem seus avatares, eu faria isso e não tentaria essa correção.


Instruções

Observe que esta é uma correção para avatares ausentes quando:

  • Os uploads são armazenados no S3
  • Os avatares estão ausentes porque foram tombstonados incorretamente
  • O registro de upload do avatar ainda existe

Faça isso em um momento de baixa atividade no seu fórum e faça um backup completo primeiro.

Instale este plugin

O plugin adiciona recover_avatars ao UploadRecovery e usa uma versão adaptada do mesmo método de restauração utilizado pelo método principal recover para recuperar uploads ausentes em posts.

Isso manterá uma cópia dos avatares “recuperados” na pasta de tombstone para redundância. Essas cópias serão removidas pelo job de fundo purge_deleted_uploads, que é executado de acordo com o período definido pela configuração do site purge_deleted_uploads_grace_period_days.

Acesse o console do Rails

Para usar o método, você precisa primeiro fazer SSH no seu servidor, entrar na instância do Docker e iniciar um console do Rails:

./launcher enter app
rails c

Faça uma execução de teste

Para ver quais uploads o método tentará recuperar do tombstone, faça primeiro uma execução de teste:

UploadRecovery.new(dry_run: true, stop_on_error: false).recover_avatars

Isso fornecerá uma lista de nomes de usuários e links de arquivos do S3. Estes são os arquivos de avatar que o método tentará mover do tombstone em uma execução real:

Saída de exemplo

user1 tombstone/original/2X/b/bc84397936074854226f1c6e9016099b7fc0aca7.jpeg
user2 tombstone/original/2X/b/b8588e7e45804406f2cbe86f2362c2ccf7f13155.jpg
user3 tombstone/original/2X/8/81a4e3b70cdc35e8f61bca87d276d0253152804a.jpeg

Compare isso com os usuários com avatares ausentes no seu site.

Faça uma execução real

Altere dry_run para false para fazer uma execução real

UploadRecovery.new(dry_run: false, stop_on_error: false).recover_avatars

Verifique

Uma vez que o job for concluído, verifique seu site ao vivo em uma nova janela anônima (para evitar problemas de cache). Assim que terminar, certifique-se de encerrar a conexão SSH ativa com seu servidor. Você não quer acidentalmente digitar algo errado no console do Rails aberto.