[img] 문자열을 포함하는 40,000개의 게시물 모두에 post.rebake!(invalidate_broken_images: true)를 실행해 보았더니 많은 이미지에서는 잘 작동했습니다… 하지만 같은 외부 이미지 호스팅 서비스를 사용했음에도 불구하고 모든 이미지에서 작동하지는 않았습니다.
예를 들어, 수천 개의 casimages 링크(유효한 이미지로 연결되고 편집 시 컴포저 미리보기에서 이미지가 표시되는 링크)는 제 스크립트 덕분에 서버에 올바르게 업로드되고 게시물의 cooked 버전에서 제대로 표시되었어야 했는데, 실제로는 깨진 상태로 남아 있었습니다. 또한 업로드가 전혀 작동하지 않은 다른 링크도 많이 있고, 그 이유를 알 수 없습니다.
Post.where('raw LIKE ?', '%[img]%').find_each do |p|
p.rebake!(invalidate_broken_images: true)
end
다른 이미지 호스팅 서비스에서 가져온 이미지 링크 중에는 업로드가 성공한 것도 있고, 그렇지 않은 것도 있습니다.
이 게시물들과 이미지 링크 사이에 어떤 차이점을 찾지 못했습니다. 모두 유효한 이미지를 가지고 있었고, 동일한 이미지 호스팅 서비스를 사용했다는 점이 제게는 의아했습니다.
여러 번 작업을 시도해 보았지만, 외부 호스팅 서비스와 관계없이 결과가 일관되지 않았습니다… 일부 이미지는 업로드되고 일부는 업로드되지 않았습니다. 마치 무작위인 것처럼 보였습니다.
저는 여기서 casimages에 대해서만 이야기할 것입니다. 다만, 제가 가져온 포럼은 다양한 다른 이미지 호스터를 사용했습니다.
그래서 저는 아마도 casimages가 제 서버에서 너무 많은 이미지를 가져오려고 하면 제 IP를 일시적으로 블랙리스트에 올린 것일지도 모른다고 생각했습니다. 이는 모든 이미지에서 작동하지 않은 사실과 이미지 업로드 성공의 무작위성을 모두 설명할 수 있습니다.
심지어 Rebuild HTML 옵션이 처음에는 작동하여 깨진 이미지 아이콘 대신 이미지가 표시된 경우조차 있었습니다(이미지는 여전히 외부 호스팅 서비스에 호스팅된 상태였지만), 외부 이미지 가져오기 Sidekiq 작업이 트리거되면 이미지가 깨졌습니다. rebake!(invalidate_broken_images: true)를 사용하는 레일 스크립트도 마찬가지였습니다.
그래서 저는 현재 더 느린 접근 방식을 시도하고 있습니다. 각 레일 rebake! 명령 사이에 5초를 기다리는 방식입니다:
total = Post.where('lower(raw) LIKE ?', '%[img]https:%').count
i = 0
Post.where('raw LIKE ?', '%[img]https:%').find_each do |p|
p.rebake!(invalidate_broken_images: true)
print "#{i}/#{total}"
print "\r"
i +=1
sleep(5)
end
약 60시간 후에 더 나아졌는지 확인할 예정입니다…
여기서 제 문제의 근본적인 원인과, (만약 casimages에 의해 일시적으로 블랙리스트에 오르지 않았다면) 왜 “정상적인” rebake가 이미지를 서버에 업로드하지 못하는지 이해하고 싶습니다.
또한 invalidate_broken_images가 실제로 무엇을 하는지 이해하지 못하겠습니다. 저는 Discourse 코드에 익숙하지 않습니다.
코드를 살펴보고 invalidage_broken_images의 발생 위치를 확인했는데, 다음과 같은 파일들을 발견했습니다:
왜 특별히 <img 문자열을 검색하는 것일까요? 제 게시물은 가져온 phpBB에서 온 것이며, raw 버전에는 [img] bbCode만 있고 <img> 태그가 없습니다. 그렇다면 제 게시물에 어떻게 영향을 미칠 수 있을까요(그리고 실제로 영향을 미쳤습니다, 이전 메시지를 참고하세요)?
또한 이 두 메서드 사이의 차이점도 잘 이해하지 못하겠습니다 (?):
rebake는 기본 인수를 false로 설정하고, rebake!은 기본 인수를 true로 설정하는 것처럼 보입니다.
이 두 메서드는 어떻게 관련되어 있나요(ruby에서 ! 문자의 용도는 알고 있습니다) 그리고 왜 다른 파일에 있는 것일까요?
제 목표는 외부 이미지가 왜 때로는 업로드되고 때로는 업로드되지 않는지 이해하고, 이를 적절하고 자동으로 업로드하는 신뢰할 수 있는 방법을 찾는 것입니다(시간당 이미지를 하나씩 업로드해야 하더라도).
거의 2주 동안 이 문제에 매달리고 있으며, 저(그리고 제가 서버를 이전해 준 사람들)를 미치게 만들고 있습니다.
또한, Discourse 로그에는 아무것도 없고, 대신 여러 개의 Sidekiq is consuming too much memory (using: 592.25M) 메시지만 있습니다. 참고로 저는 Windows 10에서 WSL을 통해 Ubuntu로 작업하고 있지만, 작동하는 솔루션을 찾으면(찾을 수 있다면…) VPS에서 사용할 의도가 있습니다.
지금 제 레일스 스크립트로 40,000개의 게시물 중 [img] 태그가 포함된 게시물을 5초 간격으로 다시 베이킹(rebaking)하는 작업을 거의 55시간째 수행하고 있습니다.
현재까지 확인한 바로는 이전보다 훨씬 잘 작동하는 것 같습니다. 대부분의 유효한 이미지(불규칙한 동작을 보이는 Imageshack는 제외)는 첫눈에 봐도 제 포럼에 완벽하게 업로드된 것으로 보입니다. 다만 100% 확신을 위해 더 자세히 살펴볼 예정입니다. 확실한 것은 결과가 훨씬, 훨씬 더 좋아졌고 일관성이 있다는 점입니다.
따라서 제가 겪었던 문제(그리고 아마도 @Amethi 님의 문제도)는 invalidate_broken_images를 통한 원격 이미지 다운로드 시 발생하는 무작위성, 즉 다양한 이미지 호스팅 제공업체의 일종의 속도 제한(rate limit)과 관련이 있었던 것 같습니다…? 이상한 점은 다른 가져온 포럼에서는 이러한 문제를 눈치채지 못했다는 것입니다…
그럼에도 불구하고, 결과가 충분히 만족스럽고 지연 시간이 원격 이미지 다운로드를 실제로 개선한다면, 프로덕션 포럼에도 동일한 방법을 적용할 것입니다. 다만 각 게시물 재베이킹 사이의 시간을 5초에서 10초 또는 15초(심지어 더 길게)로 늘릴 예정입니다. 서두를 상황이 아니며, 모두 꽤 오래된 게시물들이고, VPS 사양이 제 개인 컴퓨터보다 훨씬 낮기 때문입니다.
너무 빨리 결론을 내리고 싶지는 않지만, 제 초기 문제에 대한 해결책은 Richard 님이 제안한 해결책을 적용하는 것 AND 각 게시물 재베이킹 사이에 지연 시간을 추가하는 것 두 가지를 모두 사용하는 것일 수도 있습니다.