Как восстановить отсутствующие аватары?

Мы столкнулись с проблемой, аналогичной этой #баг:

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

Есть ли способ восстановить отсутствующие аватары?

P.S.: Я попробовал использовать это руководство и выполнил rake avatars:refresh, но ничего не произошло.

Эта проблема подобна вирусу и распространяется на всё больше аватаров! Было сделано странное наблюдение:

в Firefox некоторые аватары отображаются, тогда как в Chrome они отсутствуют. Это не означает, что в Firefox нет отсутствующих аватаров. В Firefox они тоже есть!

Снимок экрана Firefox

Снимок экрана Chrome

Эта ошибка действительно была исправлена?

Я столкнулся с той же проблемой и сейчас её расследую. В моём случае она связана с внешним хранилищем.

@Pad_Pors, вы всё ещё сталкиваетесь с этой проблемой? Также, загружали ли вы файлы или храните ли вы загрузки в S3?

Хорошо слышать, что этим занимается эксперт :ok_hand:

Да, мы все еще сталкиваемся с этой проблемой, и да, раньше файлы загружались на S3, но теперь уже нет.

У нас то же самое, @angus, у нас есть S3. Дайте знать, если понадобятся логи или что-то ещё. Большое спасибо.

В рассматриваемом мной случае отсутствующие изображения аватаров были перемещены в папку tombstone в S3 после обновления через командную строку и ручного обновления PostgreSQL с версии 10 до 12. Точная причина мне до сих пор неизвестна.

Поиск загрузок

@Jeremie_Leroy @Pad_Pors Если вы хотите проверить, наблюдается ли та же ситуация в вашем случае, вот как я искал отсутствующие аватары в папке tombstone в S3:

  1. Получил SHA1 (16-символьную строку в URL загрузки) для загрузки аватара, которая, как я знал, была повреждена после миграции. Для этого я взял идентификатор загрузки из URL повреждённого аватара (это первая часть имени файла, например, для 6254_2.png идентификатор — 6254), а затем использовал этот идентификатор, чтобы найти SHA1 загрузки в свежем дампе базы данных. Если вам неудобно работать с командной строкой, вы можете визуализировать данные из дампа с помощью графического интерфейса PostgreSQL, например Postico 2.

  2. Выполнил поиск по SHA1 в папке tombstone соответствующего бакета S3 с помощью AWS CLI.

    aws s3api list-objects --bucket <имя_бакета> --query "Contents[?contains(Key, <sha1>)]" --prefix "tombstone"
    

    (вам нужно заменить <имя_бакета> и <sha1>)

Если всё работает, вы получите список результатов, похожий на этот:

{
  "Key": "tombstone/original/2X/d/d7b553ff276fca054c7090e859ef5339fd1f936e.jpg",
  "LastModified": "2020-05-16T11:45:03+00:00",
  "ETag": ## строка из букв и цифр,
  "Size": 64580,
  "StorageClass": "STANDARD",
  "Owner": {
     "ID": ## строка из букв и цифр
   }
}

Обратите внимание: 16 мая я выполнял обновление. У всех аватаров, ошибочно перемещённых в tombstone, временные метки соответствуют этому периоду. Я подозреваю, что проблема проявлялась в продакшене с задержкой и работала периодически из-за кэширования.

Восстановление

Насколько я понимаю, UploadRecovery (и связанная с ним rake-задача) предназначена только для загрузок постов и не обрабатывает аватары, перемещённые в tombstone.

В настоящее время я изучаю возможность добавления (патчинга) нового метода в UploadRecovery, который будет использовать recover_from_s3 для восстановления загрузок аватаров.

Если кто-то знает более простой способ восстановления аватаров, ошибочно перемещённых в tombstone в S3, я готов выслушать предложения.

@tgxworld есть какие-то идеи?

Для меня это сложно. Есть ли другие люди в нашей ситуации, так что стоит ли работать над обновлением? @sam @codinghorror

Спасибо @angus за предоставление пути проверки, но мы больше не используем AWS, а также S3. На самом деле, если я не ошибаюсь, проблема возникла после того, как мы мигрировали с AWS.

Я был бы рад, если бы проблема была исправлена, но в данный момент мне гораздо проще попросить нескольких пользователей повторно загрузить свои аватары и надеяться, что проблема не распространится на новых пользователей!

Я успешно решил эту проблему на управляемом мной сайте, используя адаптированную версию той же логики, которая восстанавливает ошибочно помеченные как удалённые изображения в постах: https://github.com/discourse/discourse/blob/master/lib/upload_recovery.rb#L135.

@Jeremie_Leroy Одна из причин, по которой я привёл выше эти шаги, заключается в том, что существует несколько возможных причин отсутствия аватаров. Чтобы понять, сработает ли это в вашем случае, сначала необходимо подтвердить, что аватары ошибочно помечены как удалённые, то есть установить причину проблемы именно у вас.

Я также понимаю, что проведение такого анализа может быть очень сложным, если вы не знакомы с техническими аспектами Discourse. Я упаковал использованное мной решение в плагин, который вы можете протестировать на своём сайте. Инструкции приведены ниже.

@Pad_Pors Если вас устраивает просто попросить пользователей повторно загрузить аватары, я бы сделал именно это и не стал бы применять данный метод исправления.


Инструкция

Обратите внимание, что это исправление предназначено для случаев отсутствия аватаров, когда:

  • Загрузки хранятся в S3
  • Аватары отсутствуют из-за ошибочной маркировки как удалённые (tombstoned)
  • Запись загрузки аватара всё ещё существует

Выполняйте эти действия в период низкой активности на форуме и обязательно сделайте полную резервную копию заранее.

Установка плагина

Плагин добавляет метод recover_avatars в UploadRecovery и использует адаптированную версию того же метода восстановления, который применяется основным методом recover для восстановления отсутствующих загрузок в постах.

Это решение сохраняет копию «восстановленных» аватаров в папке tombstone для резервирования. Эти копии будут удалены фоновой задачей purge_deleted_uploads, которая выполняется в соответствии с периодом, установленным параметром сайта purge_deleted_uploads_grace_period_days.

Вход в консоль Rails

Чтобы использовать этот метод, сначала подключитесь по SSH к вашему серверу, войдите в контейнер Docker и запустите консоль Rails:

./launcher enter app
rails c

Тестовый запуск

Чтобы увидеть, какие загрузки метод попытается восстановить из tombstone, сначала выполните тестовый запуск:

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

Это выведет список имён пользователей и ссылок на файлы в S3. Это те файлы аватаров, которые метод попытается переместить из tombstone при реальном запуске:

Пример вывода:

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

Сравните этот список с пользователями, у которых на вашем сайте отсутствуют аватары.

Реальный запуск

Измените параметр dry_run на false, чтобы выполнить реальный запуск:

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

Проверка

После завершения задачи проверьте ваш рабочий сайт в новом окне инкогнито (чтобы избежать проблем с кэшированием). После завершения обязательно закройте активное SSH-подключение к вашему серверу. Не хотите случайно ввести что-то неверное в открытой консоли Rails.