Al editar y guardar publicaciones extremadamente largas (alrededor de 100.000 caracteres), nos encontramos con un problema de tiempo de espera del servidor. El servidor deja de responder durante la operación de guardado, lo que provoca errores 502/504. La consola del frontend muestra la siguiente pila de errores:
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
Realizamos algunas pruebas comparativas que sugieren que el cuello de botella está en el cálculo de la diferencia entre las versiones antigua y nueva:
Editar directamente una publicación larga A a otra publicación larga B y guardar provoca consistentemente un tiempo de espera 502/504.
Borrar primero la publicación larga, guardar un marcador de posición corto (por ejemplo, 5 caracteres), luego pegar el contenido nuevo completo B y guardar se completa rápidamente.
Parece que el motor de diferencias actual tiene dificultades con casos extremos que involucran texto muy largo combinado con un alto porcentaje de cambios. ¿Sería posible agregar un mecanismo de respaldo de rendimiento? Por ejemplo, cuando el texto es extremadamente largo y la proporción de modificaciones es alta, el sistema podría tratarlo como una «Reescritura Completa» en lugar de realizar una diferencia detallada línea por línea.
¿Tiene el equipo algún plan para optimizar el manejo de diferencias para publicaciones grandes, o introducir algún tipo de degradación elegante / protección para tales escenarios? Otra idea es permitir que el guardado se complete con éxito primero y calcular la diferencia de forma asíncrona después.
Mientras tanto, los registros del servidor de Unicorn capturaron el punto exacto del tiempo de espera, confirmando que el worker fue terminado mientras procesaba la diferencia de markdown:
El worker de Unicorn recibió la señal USR2 indicando que está a punto de agotar el tiempo de espera, volcando la traza de pila para el hilo principal
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'
...
En febrero añadí diff_too_complex: "El diff es demasiado complejo para mostrarse. Por favor, intenta ver las ediciones individuales más pequeñas.". Nuestro algoritmo de diff simplemente se detendrá si las cosas se vuelven demasiado complicadas.
¿Estás usando la última versión aquí? Debería manejar estos casos, a menos que tengas un servidor muy, muy limitado.
Antes estuve con la versión temprana de este año, ¡pero acabo de actualizar a la versión más reciente!
Después de la actualización, pude ver correctamente el mensaje «La diferencia es demasiado compleja para mostrarse» y, sinceramente, es genial. Al menos no se bloquea por completo y todavía me permite continuar y eliminar los historiales de edición.
También tiene la sensación de que el problema de congelación/retraso al editar publicaciones muy largas podría haberse solucionado. Todavía no estoy del todo seguro, pero durante mi última prueba, solo hubo un ligero retraso y, afortunadamente, se procesó correctamente la versión editada.
Voy a hacer más pruebas al respecto. ¡Muchas gracias!
Creo que el umbral de “diferencias demasiado complejas” se puede ajustar, así que si sientes que hay tal necesidad, podemos resolverlo (hay muchos factores a tener en cuenta, por lo que podría no haber una solución única para todos)
He probado esto varias veces. Incluso con ediciones lo suficientemente complejas como para activar el aviso de “La diferencia es demasiado compleja para mostrar”, el mensaje nunca ha dejado de publicarse.
Creo que este problema se ha resuelto por completo en la última versión. ¡Gracias de nuevo al equipo por el gran trabajo!