Erreur Backend 502/504 lors de la sauvegarde de modifications majeures sur de longs articles (~100k mots) en raison d'un goulot d'étranglement Diff

Lors de l’édition et de l’enregistrement de publications extrêmement longues (environ 100 000 caractères), nous avons rencontré un problème de délai d’attente côté serveur. Le serveur devient non réactif pendant l’opération d’enregistrement, ce qui entraîne des erreurs 502/504. La console du navigateur affiche la trace d’erreur suivante :

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

J’ai effectué quelques tests comparatifs qui suggèrent que le goulot d’étranglement se situe dans le calcul de la différence (diff) entre les anciennes et les nouvelles versions :

  • L’édition directe d’une longue publication A en une longue publication B et son enregistrement déclenchent systématiquement un délai d’attente 502/504.
  • Effacer d’abord la longue publication, enregistrer un court texte de substitution (par exemple 5 caractères), puis coller le nouveau contenu complet B et enregistrer s’effectue rapidement.

Il semble que le moteur de Diff actuel peine dans des cas extrêmes impliquant un texte très long combiné à un taux de modification élevé. Serait-il possible d’ajouter un mécanisme de repli (fallback) pour les performances ? Par exemple, lorsque le texte est extrêmement long et que le ratio de modification est élevé, le système pourrait le traiter comme une « Réécriture complète » au lieu d’effectuer une différence ligne par ligne détaillée.

L’équipe a-t-elle prévu d’optimiser la gestion des différences pour les publications volumineuses, ou d’introduire une sorte de dégradation gracieuse / protection pour de tels scénarios ? Une autre idée consisterait à permettre d’abord la réussite de l’enregistrement, puis à calculer la différence de manière asynchrone par la suite.

Pendant ce temps, les logs côté serveur de Unicorn ont capturé le moment exact du timeout, confirmant que le worker a été tué pendant le traitement du diff markdown :

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