긴 글(약 10만 단어)의 대규모 수정을 저장할 때 Diff 병목으로 인한 백엔드 502/504 타임아웃

매우 긴 게시글(약 10만 자)을 편집하고 저장할 때 백엔드 타임아웃 문제가 발생했습니다. 저장 작업 중 서버가 응답하지 않아 502/504 에러가 발생합니다. 프론트엔드 콘솔에는 다음과 같은 에러 스택이 표시됩니다:

ajax-error.js:36:15
l ajax-error.js:36
u ajax-error.js:75
d ajax-error.js:84
Ember 41
update rest.js:72
update rest.js:72
save rest.js:115
editPost composer.js:1147
Ember 6

몇 가지 비교 테스트를 수행해 보니 병목 현상은 이전 버전과 새 버전 간의 diff 계산에 있는 것으로 보입니다.

  • 긴 게시글 A를 긴 게시글 B로 직접 편집하여 저장하면 일관되게 502/504 타임아웃이 발생합니다.
  • 먼저 긴 게시글을 지우고 짧은 플레이스홀더(예: 5자)를 저장한 뒤, 새로운 전체 내용 B를 붙여넣고 저장하면 빠르게 완료됩니다.

현재 Diff 엔진은 매우 긴 텍스트와 높은 변경 비율이 결합된 극단적인 경우에서 어려움을 겪는 것 같습니다. 성능 폴백 메커니즘을 추가할 수 있을까요? 예를 들어, 텍스트가 매우 길고 수정 비율이 높은 경우, 상세한 라인별 diff를 수행하는 대신 시스템이 이를 “완전 재작성”으로 처리하도록 할 수 있습니다.

팀에서 큰 게시글의 Diff 처리를 최적화하거나, 이러한 시나리오에 대한 그레시울 디그레이드(점진적 성능 저하) 또는 보호 장치를 도입할 계획이 있습니까? 다른 아이디어로는 저장을 먼저 성공시키고, 이후 diff를 비동기적으로 계산하는 방식이 있습니다.

한편, 서버 측 Unicorn 로그는 타임아웃이 발생한 정확한 시점을 기록하여, 워커가 마크다운 diff를 처리하는 동안 종료되었음을 확인했습니다:

Unicorn worker received USR2 signal indicating it is about to timeout, dumping backtrace for main thread
config/unicorn.conf.rb:204:in `backtrace'
config/unicorn.conf.rb:204:in `block (2 levels) in reload'
/var/www/discourse/lib/discourse_diff.rb:172:in `[]'
/var/www/discourse/lib/discourse_diff.rb:172:in `tokenize_markdown'
/var/www/discourse/lib/discourse_diff.rb:115:in `side_by_side_markdown'
/var/www/discourse/app/serializers/post_revision_serializer.rb:128:in `body_changes'
... 

UNICORN_TIMEOUT을 60이나 120으로 변경하면 위의 문제를 해결할 수 있나요?

안녕하세요,

이 이슈를 #contribute:bug으로 옮길 것 같습니다. 10만 자는 매우 이례적인 상황이지만, 어쨌든 어떤 형태의 폴백(fallback)은 구현되어야 한다고 생각합니다.

2월에 diff_too_complex: "차이가 너무 복잡하여 표시할 수 없습니다. 개별적으로 더 작은 편집을 확인해 주세요."를 추가했습니다. 상황이 너무 복잡해지면 우리의 diff 알고리즘은 단순히 작업을 중단합니다.

여기서 최신 버전을 실행 중인가요? 이 경우를 처리해야 하지만, 서버 사양이 매우 낮은 경우를 제외하고는요.

올해早些에 나온 초기 버전을 사용하다가, 방금 최신 버전으로 업데이트했습니다!

업데이트 후 "차이가 너무 복잡해서 표시할 수 없습니다"라는 메시지를 성공적으로 확인했고, 솔직히 정말 좋습니다. 적어도 하드 크래시는 하지 않고, 편집 이력을 삭제하는 작업도 계속 진행할 수 있습니다.

또한, 거대한 게시물을 편집할 때 발생하는 동결/지연 문제가 이제 수정되었을 수도 있다는 느낌이 듭니다. 아직 확신은 못 하겠지만, 마지막 테스트에서는 잠시 지연된 후 다행히도 편집된 버전을 성공적으로 처리했습니다.

이 부분에 대해 더 많은 테스트를 해보겠습니다. 정말 감사합니다!

놀랍네요 :+1:

“diff too complex” 임계값을 조정할 수 있다고 생각해요. 그런 필요가 있다고 느끼시면 함께 방법을 찾아볼 수 있을 거예요 :+1: (고려해야 할 요소가 많아서, 모든 상황에 적용되는 단일 솔루션이 없을 수도 있어요)

이 문제를 여러 번 테스트해 보았습니다. “차이가 너무 복잡하여 표시할 수 없습니다” 알림이 표시될 만큼 복잡한 편집을 하더라도, 게시물이 게시에 실패한 적은 한 번도 없었습니다.

이 문제가 최신 버전에서 완전히 해결되었을 것이라고 생각합니다. 훌륭한 작업을 해주신 팀에 다시 한번 감사드립니다!