Intentando solucionar el retraso de 10 minutos

Planeo usar el plugin wp-discourse en un sitio web de pronóstico del tiempo de la costa del Golfo que normalmente tiene entre 10 y 20 mil visitas a páginas por día, pero que ocasionalmente, durante eventos climáticos severos, puede alcanzar entre 1.5 y 2 millones de visitas a páginas por día para aproximadamente 500-700 mil visitantes. El sitio y su estrategia de alojamiento han sido probados en batalla a través de varios eventos climáticos severos y las cosas funcionan muy bien bajo presión, principalmente gracias a un diseño cuidadoso y a la gran ayuda de Cloudflare.

Los usuarios del sitio están acostumbrados a una experiencia de comentarios de baja fricción a través de los comentarios nativos de WordPress, por lo que habrá un período de adaptación (como acostumbrarlos a hacer clic en el enlace “Continuar la discusión en…”) que el personal de cara al público está preparado para gestionar.

Sin embargo, lo que no tolerarán es el retraso variable de 10 minutos entre la publicación de los comentarios y su visualización en la página de la publicación diaria de WordPress. Querrán que los nuevos comentarios (hasta el límite configurado) aparezcan inmediatamente en la página de inicio al publicarlos, de manera similar a como los comentarios nativos de WP se muestran inmediatamente después de publicarlos.

Después de jugar con las opciones integradas para intentar que las publicaciones aparezcan inmediatamente sin la caché fastcgi de nginx, WordPress o la caché del navegador que interfieren con la aparición de nuevos comentarios al actualizar después de que se publican, he agregado los siguientes dos mu-plugins para mitigar esto y hacer que los comentarios recién publicados aparezcan en el lado de WordPress al actualizar:

wp-discourse-transient-killer.php
wp-discourse-cache-header-fix.php

Esto ha resuelto mi problema: las nuevas publicaciones en los hilos de Discourse creados por WordPress ahora aparecen debajo de las publicaciones de WordPress instantáneamente al actualizar.

Pero estoy al límite de mi competencia aquí: ¿qué estoy rompiendo/estropeando/socavando al hacer esto?

No me importa particularmente generar una carga adicional en mi proveedor de alojamiento web al tener el punto final de comentarios bombardeado por visitantes que consultan la página de pronóstico del tiempo diario (con sus comentarios de Discourse incrustados): ese es un problema que puedo resolver gastando dinero. Mi requisito principal es evitar que más de 20.000 usuarios me envíen correos electrónicos preguntando por qué sus comentarios no aparecen instantáneamente en la página de inicio cuando los publican.

¿Es este el enfoque correcto? ¿Es sensato lo que estoy haciendo? ¿Crea problemas de seguridad o rendimiento adicionales que no he anticipado? Básicamente, ¿estoy estropeando las cosas al hacer esto?

Gracias :slight_smile:

Hmm, estoy confundido por qué esto funciona, porque

Y tu plugin

add_action( 'wpdc_after_webhook_post_update', function( $topic_ids ) {
    foreach ( (array)$topic_ids as $topic_id ) {
        delete_transient( 'wpdc_comment_html_' . $topic_id );
    }
}, 11 );

¿No estás mezclando los $post_ids (de Wordpress) pasados a la acción con el topic_id (de Discourse) que sirve como clave transitoria?

Esperaría que tu plugin se viera así:

add_action( 'wpdc_after_webhook_post_update', function( $post_ids) {
    foreach ( (array)$post_ids as $post_id ) {
        $topic_id = get_post_meta( $post_id, 'discourse_topic_id', true );
        delete_transient( 'wpdc_comment_html_' . $topic_id );
    }
}, 11 );

Por otro lado, ¿estás diciendo que esto funciona? :thinking:

Hola @Lee_Ars, ¿puedes confirmar primero que tienes configurado el webhook de comentarios?

Eso funciona así:

  1. Hay una nueva publicación en Discourse.
  2. Se envía una carga útil de webhook a Wordpress.
  3. WP discourse actualiza el recuento de comentarios en la publicación y también establece un campo personalizado de publicación wpdc_sync_post_comments.
  4. Si se establece wpdc_sync_post_comments, los comentarios de Discourse se sincronizarán cuando se cargue una publicación de Wordpress, independientemente del período de sincronización (es decir, el retraso de 10 minutos).

Antes de entrar en el tema del almacenamiento en caché, solo quiero asegurarme de que eso esté implementado primero. Si es así, quizás también activa los “Registros detallados de webhooks” y verifica que estás recibiendo solicitudes de webhook cuando se crea una nueva publicación en Discourse.

1 me gusta

¡Hola Angus! Eso es afirmativo, la opción de webhook “Sync Comment Data” está habilitada en el lado de WP, y creé el webhook en el lado de Discourse y los pings son exitosos. El registro del plugin de WP muestra mensajes comment.INFO: sync_comments.success en las marcas de tiempo correctas:

[2025-07-07 14:16:38] connection.INFO: check_connection_status.successful_connection
[2025-07-07 14:16:38] connection.INFO: check_connection_status.valid_scopes
[2025-07-07 20:11:31] comment.INFO: sync_comments.success {"post_id":786}
[2025-07-07 20:25:03] comment.INFO: sync_comments.success {"post_id":786}
[2025-07-07 20:32:14] comment.INFO: sync_comments.success {"post_id":786}
[2025-07-07 20:44:15] comment.INFO: sync_comments.success {"post_id":786}
[2025-07-07 21:00:39] comment.INFO: sync_comments.success {"post_id":786}
[2025-07-07 21:01:42] comment.INFO: sync_comments.success {"post_id":786}
[2025-07-07 21:15:40] comment.INFO: sync_comments.success {"post_id":786}

Es solo que, incluso con esos mensajes de éxito, los visitantes existentes (o al menos yo, probando repetidamente en Firefox/Safari/Chrome en un Mac, Firefox/Chrome/Edge en un PC con Win10 y Safari en iOS) siguen recibiendo un endpoint /wp-json/wp-discourse/v1/discourse-comments en caché, con encabezados cache-control establecidos en una cantidad distinta de cero. Si hago un ctrl-shift-f5 en Chrome (o el equivalente en otros navegadores) para forzar el bypass de la caché local al actualizar, todo funciona perfectamente y aparecen las nuevas publicaciones.

Con los mu-plugins en su lugar, ese endpoint muestra cache-control establecido en no-store no-cache, etc., y el comportamiento problemático no se manifiesta; simplemente visitar la publicación de WP o actualizarla con el botón de actualización normal muestra los nuevos comentarios incrustados.

He activado el registro detallado de webhooks y he publicado una publicación de prueba, y las cosas parecen estar bien cuando creo una nueva publicación:

webhook_topic.INFO: update_topic_content.update_post_metadata_success {"post_ids":"786"}

Todo parece estar funcionando, pero todavía no entiendo realmente por qué se manifestó el comportamiento problemático original, o si surgió de algún problema pasado por alto de mi parte. (¡Muy posible!)

D’oh, lo siento, estoy seguro de que tienes razón en que lo arruiné, ayer fue un día largo y, como dije, estoy un poco al límite de mis capacidades aquí. Definitivamente estaba haciendo algo, aunque ahora me pregunto si el comportamiento “corregido” que estoy viendo es solo que está roto de una nueva manera. (¡He actualizado el plugin “transient killer” para usar el argumento correcto ahora, gracias!)

Gracias, solo una cosa más para aclarar. ¿Está activada esta configuración de WP Discourse (en “Comentar”)?

He probado ambas opciones con la configuración Cache Comment HTML habilitada o deshabilitada y parece no tener ningún impacto en el comportamiento problemático. Actualmente la tengo deshabilitada, pero puedo configurarla como sea útil para la solución de problemas.

Si la configuración está desactivada, no notarás la confusión topic_id / post_id, ya que ese plugin no hace nada en ese caso. Sin caché → no importa si eliminas la caché incorrecta.

Si la configuración está activada, deberías notar que el plugin no funciona correctamente.

Es decir, si quieres solucionar problemas, deberías activar la configuración.

1 me gusta

Ok, como primera medida para tu caso sugeriría:

  1. mantener deshabilitado el HTML de comentarios de caché; y
  2. eliminar el plugin https://www.bigdinosaur.org/r/wp-discourse-transient-killer.txt ya que actualmente no hace nada, como observa Richard.

Si eso no resuelve el problema, entonces el problema está relacionado con otra forma de caché. Las siguientes preguntas a responder son:

  1. ¿Qué soluciones de caché utilizas tú (y/o tu proveedor de hosting) para Wordpress?
  2. Si https://www.bigdinosaur.org/r/wp-discourse-cache-header-fix.txt soluciona el problema, ¿cómo invalida su comportamiento específico la caché que se está aplicando en el punto 1?

Mirando wp-discourse-cache-header-fix veo que una de las correcciones es para load-comments.js. ¿Tienes habilitada esta configuración?

Se trata de una instalación de WP autoalojada en nginx+php-fpm 8.3 con caché fast-cgi de nginx para contenido dinámico y caché de objetos Redis (con el drop-in de caché de objetos activo). No hay otras capas (sin CDN, sin CF, sin Varnish en el servidor u otra caché local más allá de la caché fast-cgi de nginx). Volcar la caché fast cgi de nginx (agresivamente, ejecutando rm -rf /etc/nginx/cache/*) no tiene ningún efecto en el comportamiento problemático: se sirven resultados obsoletos incluso después de borrar el directorio de caché y reiniciar tanto nginx como php-fpm.

De hecho, tengo activada la carga de comentarios Ajax en este momento, sí, pero de nuevo, desactivarla (y volcar la caché de nginx y reiniciar nginx y php-fpm por si acaso) no tuvo ningún efecto en el comportamiento problemático. Los navegadores seguían mostrando comentarios obsoletos.

Opción cambiada, transient-killer eliminado. No hay cambios en el comportamiento del problema.

El efecto que aplica parece ser el suministro de una cabecera cache-control de no caché en lugar de una con un tiempo de caché especificado. Sin ella, mi navegador parece querer mucho servir una versión en caché obsoleta del endpoint wp-json/wp-discourse/v1/discourse-comments desde su caché de disco; como se mencionó, tengo que presionar shift-ctrl-f5 (o el equivalente) para forzar una actualización sin caché.

El comportamiento problemático parece estar en el lado del navegador, en lugar de en una caché persistente del servidor. Son todos los navegadores en todos los sistemas operativos a los que tengo acceso los que lo hacen.

Ok. Para que quede 100% claro. Cuando tienes

  • Webhook de comentarios verificado y funcionando

  • Caché de comentarios HTML desactivada

  • Carga AJAX desactivada

  • sin cdn

  • sin cloudfront

  • sin plugin de caché de wordpress

  • sin advertencias o errores relevantes en los logs de php

¿estás seguro de que no funciona?

Si no funciona con esa configuración, me faltan opciones sin echar un vistazo más de cerca y optaría por

  • Carga AJAX activada
  • Tus correcciones de wp-discourse-cache-header-fix.php

que es lo que sospecho que te funcionaba. Si esa ruta funciona, deberías optar por ella.

Aquí tienes una rápida galería de imgur con capturas de pantalla de la configuración actual de mi plugin, como referencia.

Confirma que no hay CDN, ni Cloudfront ni Cloudflare, ni plugins de caché aparte del helper de Nginx (para ayudar a WP a invalidar la caché fast-cgi de nginx según sea necesario).

También confirma que no hay nada relevante en los registros de errores de php-fpm ni de nginx.

Dios, tío, ojalá lo estuviera. Llevo dándole vueltas a esto unas 30 horas, con algunos descansos para dormir. Puede que esté empezando a ver doble, jeje.

Sí, te entiendo. Tómate un descanso por un día o así. Intentaré recrear el problema mañana copiando tu configuración.

2 Me gusta

Si no logro encontrar una solución por mi cuenta, y si te parece bien, estaré encantado de conceder acceso local temporal (al blog de WP, al discourse y/o a los hosts subyacentes) para la resolución de problemas. Definitivamente no estoy intentando conseguir mano de obra gratuita ni nada por el estilo. Estaría encantado de pagar por tus servicios si hay tiempo real que dedicar aquí.

Ok, aquí tienes un video mío intentando (y fallando) reproducir tu problema:

Lo siguiente que quiero que intentes es este filtro.

Gracias @angus — que no se pueda reproducir en realidad me hace sentir mucho mejor, porque eso significa que estoy haciendo algo mal en lugar de que realmente haya algo mal :smiley:

Añadiré ese filtro hoy cuando tenga un bloque de tiempo para solucionar problemas y te informaré :+1:

1 me gusta

Respondiendo un mes y pico después para cerrar el ciclo: todavía estoy experimentando algunas rarezas en el despliegue a producción completa (sitio prod, ejemplo de publicación en sitio prod con incrustación de Discourse, foro real de Discourse), pero todo es manejable. Voy a atribuir cualquier problema de latencia/retraso restante a la compleja capa de pastel que es Wordpress + Discourse + Cloudflare, y a mi agresiva estrategia de caché para mantener todas estas cosas operativas durante las tormentas de tráfico que resultan de tormentas reales.

Gracias por tomarte el tiempo de responder, @angus <3

1 me gusta

Disculpas por volver a subir esto, pero quería dar seguimiento e informar que ¡encontré la causa del problema! Y fue mi maldita culpa, como de costumbre.

Muy brevemente, guardo detalles comunes de bloques de ubicación de PHP en un fragmento en /etc/nginx/snippets/ para poder incluirlos en múltiples archivos vhost sin tener que duplicarlos cada vez. Ha pasado mucho tiempo (años, probablemente) desde que revisé ese fragmento, y efectivamente, había un add_header Cache-Control "public, max-age=7200"; espurio allí, que se aplicaba a todo lo que salía de ese bloque de ubicación.

Así que lo eliminé, vacié todas las capas de caché y, he aquí, el comportamiento problemático desapareció.

Gracias de nuevo por tomarte el tiempo de trabajar conmigo, @angus, aunque al final resultó ser nuevamente otro problema de Discourse hecho por mí :people_hugging:

3 Me gusta

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.