URL completa en archivo de assets ERB → problemas multisitio

La nueva implementación del service worker de Workbox utiliza UrlHelper.absolute. Dado que se trata de un activo compilado, almacena la URL completa, que incluye el nombre de host completo del host principal en un entorno multisitio.

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/service-worker.js.erb#L3-L6

Creo que debería utilizar UrlHelper.local_cdn_url en su lugar. Esto también evita la necesidad de recompilar los activos tras cambiar el nombre de host.

1 me gusta

Creo que el consenso general es que los Service Workers nunca deberían ser servidos desde un CDN:

Ah, ¿te refieres a los archivos importScripts? ¿Tienes un clúster multisitio donde cada sitio tiene una URL de CDN diferente?

1 me gusta

Sí, importScripts y modulePathPrefix, en las líneas 3 y 6 de ese archivo ERB.

Pero no me estás entendiendo completamente. Los problemas ocurren donde no hay CDN en un clúster multisitio.

Tanto UrlHelper.absolute como UrlHelper.local_cdn_url pueden manejar situaciones con y sin CDN.

absolute:

sin CDN: https://primarysite.ofmultisitecluster.com/javascripts/workbox/workbox-sw.js malo: origen remoto para todos los sitios excepto el principal, exponiendo el nombre de host del clúster principal
con CDN: //cdnurl/javascripts/workbox/workbox-sw.js

local_cdn_url:

sin CDN: /javascripts/workbox/workbox-sw.js bueno: URL relativa
con CDN: //cdnurl/javascripts/workbox/workbox-sw.js

por lo tanto, la segunda opción es la que queremos.

El problema es que esas líneas (3 y 6) no se refieren al archivo del service worker.

El service worker proviene del dominio base (ya que no puede ser servido desde un CDN), pero este service worker importa scripts de forma perezosa en tiempo de ejecución (en este caso, los archivos de la librería Workbox), y esos sí pueden ser servidos desde un CDN.

Por lo tanto, el problema es que tu clúster multisitio no tiene un CDN configurado, lo que expone este error, el cual queda enmascarado cuando DISCOURSE_CDN está establecido. Solo quería saber por qué no nos afecta a nosotros.

1 me gusta

Tienes razón, he editado mi segundo mensaje para corregir mis errores. No se trata del archivo del service worker, sino que está dentro del archivo del service worker.

Sí, exactamente en ese momento es cuando se expone el error.

3 Me gusta

Solo quería confirmar: ¿mi diagnóstico es correcto y se trata de un error que será corregido? ¿Hay algo que necesiten de nosotros que pueda ayudar?

3 Me gusta

Sí, parece un error que necesita ser corregido. ¡Lo atenderé esta semana!

3 Me gusta

Hmmm, acabo de probarlo en una consola de Meta:

## Actual
[1] pry(main)> UrlHelper.absolute("/javascripts/workbox/workbox-sw.js")
=> "https://d3bpeqsaub0i6y.cloudfront.net/javascripts/workbox/workbox-sw.js"

### Cambio propuesto
[2] pry(main)> UrlHelper.local_cdn_url("/javascripts/workbox/workbox-sw.js")
=> "/javascripts/workbox/workbox-sw.js"

Esas funciones no me parecen intercambiables.

3 Me gusta

Tienes razón, local_cdn_url reemplaza una URL local por una URL de CDN. Y ni siquiera es una URL local, sino relativa.

Así que creo que esto sería suficiente en lugar de esas llamadas a UrlHelper?

importScripts("<%= (Discourse.asset_host || '') + "/javascripts/workbox/workbox-sw.js" %>");

y

modulePathPrefix: (Discourse.asset_host || '') + "/javascripts/workbox",

1 me gusta

Al leer la implementación actual de UrlHelper.absolute:

Parece que construye la URL concatenando Discourse.base_url_no_prefix con el parámetro cuando el CDN es nil, que es tu caso.

Entonces, ¿el problema es que Discourse.base_url_no_prefix siempre devuelve el primer host en un entorno multisitio?

Analizando el código :eyes:

el nombre de la variable aquí current_hostname en la línea 288 sugiere fuertemente que es consciente del entorno multisitio :thinking:

y por

parece que lo es. De momento, es un callejón sin salida…

Buscando en otro lugar, esta ruta ganó un tratamiento especial porque los navegadores tienden a bombardearla MUCHO, y no podemos colocarla en un CDN para convertirlo en un problema de terceros. Al hacerlo, tuvimos un error relacionado con una fuga en el entorno multisitio, que fue corregido por @sam hace un año:

¿Existe la posibilidad de que la forma en que estás sirviendo este clúster multisitio esté cacheando esta ruta de manera que cause fugas, como ocurría a principios de 2018?

2 Me gusta

No, el problema es que ocurre eso al precompilar los activos, lo cual se convierte en un problema en entornos multisitio.
La solución es no incluir nunca el nombre de host en los activos (excepto si se trata de un CDN de activos, ya que este siempre se comparte entre los hosts multisitio de todos modos).

1 me gusta

@falco ¿Viste mi solución propuesta dos publicaciones arriba de esta?

Sí, pero en mis pruebas no cubre las subcarpetas sin CDN :sob:

Creo que necesitaremos usar:

"#{Discourse.asset_host}#{Discourse.base_prefix}/javascripts/workbox"
1 me gusta

Buen punto sobre la subcarpeta.

Pero… Discourse.asset_host puede ser nil y nunca he oído hablar de Discourse.base_prefix.

¿Qué te parece esto:

importScripts("<%= (Discourse.asset_host || GlobalSetting.relative_url_root) + "/javascripts/workbox/workbox-sw.js" %>");

modulePathPrefix: "<%= (Discourse.asset_host || GlobalSetting.relative_url_root) + "/javascripts/workbox" %>",

Eso es exactamente lo que queremos en este caso:

irb(main):001:0> puts "a#{nil}bc"
abc

Oh, me refería a Discourse.base_path.

Acabo de enviar una corrección, por favor echa un vistazo.

3 Me gusta

Parece bien para nuestro caso… ¡gracias!

Pero… solo para asegurarme… no estoy seguro de cómo están manejando los recursos en un CDN en combinación con una subcarpeta, pero si usan Discourse.asset_host, ¿todavía añaden el prefijo de la ruta de la subcarpeta a todas las rutas en el host de recursos también? Porque eso es lo que está haciendo el código ahora.
Si eso es lo que están haciendo, entonces pueden ignorar completamente este párrafo :slight_smile:

3 Me gusta

Todo este asunto de subcarpetas + CDN nos causó bastantes problemas. @featheredtoast realizó algunos trabajos para agilizar esto y dedicamos mucho tiempo a asegurarnos de que todo nuestro código de entrega de activos funcione correctamente con esas combinaciones extrañas de buckets, subcarpetas, etc.

Creo que estamos seguros :smile:, pero si es necesario, podemos volver a abrir esto.

¡Gracias por el informe del error!

8 Me gusta

Este tema se cerró automáticamente después de 7 días. Ya no se permiten nuevas respuestas.