Durante la modifica e il salvataggio di post estremamente lunghi (circa 100.000 caratteri), abbiamo riscontrato un problema di timeout lato backend. Il server diventa non rispondente durante l’operazione di salvataggio, generando errori 502/504. La console del frontend mostra la seguente traccia dell’errore:
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
Ho eseguito alcuni test comparativi che suggeriscono come il collo di bottiglia sia nel calcolo della differenza tra le versioni vecchia e nuova:
Modificare direttamente un lungo post A in un lungo post B e salvarlo innesca costantemente un timeout 502/504.
Cancellare prima il post lungo, salvare un segnaposto breve (ad esempio 5 caratteri), quindi incollare il contenuto nuovo completo B e salvarlo si completa rapidamente.
Sembra che il motore Diff attuale abbia difficoltà con casi estremi che coinvolgono testo molto lungo combinato con un’alta percentuale di modifiche. Sarebbe possibile aggiungere un meccanismo di fallback per le prestazioni? Ad esempio, quando il testo è estremamente lungo e il rapporto di modifica è elevato, il sistema potrebbe trattarlo come una “Riscrittura Completa” invece di eseguire un diff dettagliato riga per riga.
Il team ha in programma di ottimizzare la gestione del Diff per i post di grandi dimensioni o di introdurre una sorta di degradazione graduale / protezione per tali scenari? Un’altra idea è consentire il salvataggio con successo prima e calcolare il diff in modo asincrono in seguito.
Nel frattempo, i log server-side di Unicorn hanno catturato il punto esatto del timeout, confermando che il worker è stato ucciso durante l’elaborazione del diff della 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'
...
Penso che sposterò questa discussione in Contribute > Bug. 100k caratteri è molto insolito, ma indipendentemente da ciò, penso che dovrebbe essere implementato un qualche tipo di fallback.
A febbraio ho aggiunto diff_too_complex: "La differenza è troppo complessa da visualizzare. Si prega di provare a visualizzare le modifiche singole e più piccole.". Il nostro algoritmo di diff si interrompe semplicemente se le cose diventano troppo complicate.
Stai utilizzando l’ultima versione qui? Dovrebbe gestire questi casi, a meno che tu non abbia un server molto molto sottodimensionato.
Ho già provato la versione iniziale di quest’anno, ma ho appena effettuato l’aggiornamento all’ultima versione disponibile!
Dopo l’aggiornamento, sono riuscito a visualizzare correttamente il messaggio «La differenza è troppo complessa per essere visualizzata» e, onestamente, è fantastico. Almeno non si blocca in modo critico e mi permette comunque di procedere con l’eliminazione della cronologia delle modifiche.
Sembra inoltre che il problema di congelamento/lentezza durante la modifica di post molto lunghi possa essere stato risolto. Non ne sono ancora del tutto certo, ma durante il mio ultimo test la lentezza è durata solo un attimo e, per fortuna, la versione modificata è stata elaborata con successo.
Credo che la soglia per “diff troppo complessa” possa essere modificata, quindi se ritieni che ce ne sia bisogno, possiamo trovarla insieme (ci sono molti fattori da considerare, quindi potrebbe non esistere una soluzione valida per tutti)
L’ho testato più volte. Anche con modifiche abbastanza complesse da attivare l’avviso “La diff è troppo complessa da visualizzare”, il post non ha mai smesso di essere pubblicato.
Credo che questo problema sia stato risolto completamente nell’ultima versione. Grazie ancora al team per il ottimo lavoro!