Backend 502/504 Timeout beim Speichern größerer Änderungen an langen Beiträgen (~100k Wörter) aufgrund von Diff-Engpass

Beim Bearbeiten und Speichern extrem langer Beiträge (ca. 100.000 Zeichen) sind wir auf ein Backend-Timeout-Problem gestoßen. Der Server reagiert während des Speichervorgangs nicht mehr, was zu 502/504-Fehlern führt. In der Frontend-Konsole erscheint die folgende Fehlerstapelmeldung:

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

Ich habe einige Vergleichstests durchgeführt, die darauf hindeuten, dass der Flaschenhals in der Berechnung der Differenz zwischen der alten und der neuen Version liegt:

  • Das direkte Bearbeiten eines langen Beitrags A zu einem langen Beitrag B und das anschließende Speichern löst konsistent einen 502/504-Timeout aus.
  • Das Leeren des langen Beitrags, das Speichern eines kurzen Platzhalters (z. B. 5 Zeichen), das Einfügen des vollständigen neuen Inhalts B und das anschließende Speichern erfolgt schnell.

Es scheint, dass die aktuelle Diff-Engine mit extremen Fällen kämpft, die aus sehr langem Text in Kombination mit einem hohen Prozentsatz an Änderungen bestehen. Wäre es möglich, einen Leistungs-Fallback-Mechanismus hinzuzufügen? Zum Beispiel könnte das System den Vorgang als „Vollständige Neuformatierung“ behandeln, wenn der Text extrem lang ist und das Änderungsverhältnis hoch ist, anstatt eine detaillierte zeilenweise Diff-Berechnung durchzuführen.

Hat das Team Pläne, die Diff-Behandlung für große Beiträge zu optimieren oder eine Art graceful degradation / Schutz für solche Szenarien einzuführen? Eine weitere Idee wäre, das Speichern zunächst erfolgreich abzuschließen und die Diff-Berechnung asynchron im Hintergrund durchzuführen.

2 „Gefällt mir“

In der Zwischenzeit haben die Server-seitigen Unicorn-Logs den genauen Zeitpunkt des Timeouts erfasst und bestätigt, dass der Worker während der Verarbeitung des Markdown-Diffs beendet wurde:

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'
... 

Kann ich das oben genannte Problem lösen, indem ich UNICORN_TIMEOUT auf 60 oder 120 ändere?

Hey,

Ich denke, ich werde das in Contribute > Bug verschieben. 100k Zeichen sind sehr ungewöhnlich, aber unabhängig davon sollte meiner Meinung nach ein Fallback implementiert werden.