Realizamos la actualización con éxito hace un par de meses. Publicamos nuestra experiencia aquí para cualquier persona que pueda tener la misma pregunta en el futuro.
Discourse ofrece cierto soporte para actualizaciones sin tiempo de inactividad mediante migraciones posteriores al despliegue. El proceso general, tal como lo entendimos, se puede dividir en 2 pasos.
PASO 1: Actualizar a la nueva versión y ejecutar migraciones seguras:
- Actualizar todos los plugins y temas para que sean compatibles con la nueva versión. (Esto requiere bastante trabajo, dependiendo de tu configuración).
- Generar tu archivo web_only.yml con el siguiente contenido:
version: <NUEVA_VERSION>
SKIP_POST_DEPLOYMENT_MIGRATIONS=1 - Inicializar (
./launcher bootstrap web_only) - Reiniciar tus servidores
PASO 2: Ejecutar la migración posterior al despliegue (migraciones de alto riesgo, como eliminación de columnas y tablas, etc.). Para este punto, este paso debería ser seguro, ya que todos tus servidores están ejecutando la nueva versión del código y no deberían depender de los datos que se eliminarán:
- Generar tu archivo web_only.yml con:
version: <NUEVA_VERSION>
SKIP_POST_DEPLOYMENT_MIGRATIONS=0 - Inicializar (
./launcher bootstrap web_only) - Reiniciar tus servidores
Complicaciones:
Decidimos ejecutar el PASO 1 y el PASO 2 en fechas diferentes, lo que causó algunos problemas. Hubo una gran reestructuración en el modelo de encuestas entre las versiones 2.1 y 2.3. Parece que inicialmente la mayoría de los datos de las encuestas se almacenaban como un objeto JSON en la tabla post_custom_fields. Para la versión 2.3, estos datos se movieron a su propia tabla polls. Esto requirió una migración de datos que se realizó como parte de las migraciones posteriores al despliegue (PASO 2).
Nuestro problema específico fue que, inmediatamente después de migrar a la versión 2.3, las encuestas creadas antes de la actualización se rompieron, probablemente porque el código que las renderizaba asumía el nuevo modelo de datos. Algunos usuarios notaron esto e intentaron actualizar manualmente las encuestas desde la interfaz de usuario, lo que provocó que se crearan registros en la nueva tabla polls. Estos registros, como descubrimos más tarde con tristeza, activaban una restricción de unicidad de PostgreSQL durante el proceso de inicialización, deteniéndolo efectivamente.
Para evitar esto, decidimos aplicar un parche que omitiera una migración de encuestas específica si ya existía en la base de datos. Esta no fue una solución perfecta, ya que se podría perder información de post_custom_fields que nunca se migra para estos posts. Pero en nuestro caso, esto seguía siendo un buen compromiso, ya que el número de casos era muy bajo en todo nuestro sistema (2 instancias que pudimos observar) y nos permitió ejecutar el proceso de inicialización. Ahora, probar y aplicar el parche planteó dos preguntas más:
-
¿Cómo probamos el cambio antes de enviar la PR?
Queríamos probar nuestro código bajo las mismas condiciones en las que se ejecutaría en la realidad, lo que significaba probarlo contra el proceso de inicialización. Esto no es tan trivial como probar cambios en el código de tiempo de ejecución, que puedes hacer ejecutando la aplicación independiente de Discourse localmente. -
¿Cómo incorporamos los cambios en nuestro sistema?
No queríamos esperar a que el parche llegara a una versión oficial de Discourse, lo cual puede ser un proceso largo y básicamente nos obligaría a realizar otra actualización. Ya teníamos clientes quejándose de las encuestas existentes y cuanto más esperábamos, mayores eran las posibilidades de que los clientes modificaran manualmente las encuestas, agravando los problemas de integridad de los datos.
Así que encontramos una forma de probar los cambios que estábamos introduciendo modificando el origen del repositorio que utiliza el script de inicialización. Esto requirió algunos ensayos y errores, ya que no tenemos mucho conocimiento sobre pups y otras herramientas relacionadas con este proceso. Al final, hicimos algo como esto.
Esto nos permitió verificar que nuestra corrección funcionaba como se esperaba. También pudimos inicializar una nueva imagen en producción desde nuestra propia versión modificada de Discourse que contenía el parche, sin tener que esperar a una versión oficial de Discourse.