Cómo pasar a espacios de trabajo más grandes sin hacer esperar a nadie
Cada proyecto de Mythex tiene su propio espacio de trabajo: un pequeño ordenador en la nube donde el agente escribe código y se ejecuta la vista previa de tu app. Habíamos subido la memoria de los espacios nuevos de 1 GB a 2 GB, pero los antiguos se quedaron en 1 GB: el día que lo comprobamos, alrededor de una cuarta parte. Nuestra primera solución movía un proyecto a un espacio más grande cuando se volvía a abrir. El primer día en producción, eso hizo esperar siete minutos a una persona. Pusimos un límite de tiempo estricto y, después, sacamos el traslado de la apertura de proyectos por completo.
Por qué los espacios antiguos se quedaron pequeños
Nuestro proveedor de sandboxes fija el tamaño de un espacio de trabajo al crearlo, y lo mantiene en cada pausa y reanudación. Cambiar la plantilla —la receta con la que se construyen los espacios nuevos— solo afecta a los espacios creados después del cambio. Nada redimensiona los que ya existen.
Eso importaba. Uno de los espacios pequeños se quedó sin memoria durante un git push mientras arrancaba su vista previa, y dejó de responder durante 11 minutos. Por eso falló una publicación.
Primer intento: mover el proyecto al despertar
Los espacios de trabajo se pausan cuando nadie los usa y se despiertan cuando se abre el proyecto. Despertarlo parecía el momento adecuado para mover un proyecto, porque nadie está trabajando en él todavía.
El traslado funcionaba así:
- Comprobar el tamaño. Si el espacio es menor de 2 GB, lo movemos. Si su tamaño es desconocido, no hacemos nada.
- No interrumpir una publicación. Una publicación lee los archivos del espacio, así que si hay una en curso, omitimos el traslado.
- Empaquetar el proyecto. Archivar todo lo del proyecto —incluido su historial de git, que son todos los checkpoints del proyecto, y el archivo
.envde la app, que pertenece al propietario— pero dejar fuera las dependencias instaladas (node_modules), que pueden reinstalarse. - Copiarlo directamente. Transmitir el archivo desde el espacio antiguo a uno nuevo de 2 GB, para que nunca tenga que caber en la memoria de nuestro propio servidor.
- Comparar antes de cambiar. Contar los archivos, leer el último checkpoint y contar los checkpoints, en ambos espacios. Cambiar solo si los tres coinciden.
- Conservar el antiguo ante cualquier fallo. Cualquier error o cualquier discrepancia descarta el espacio nuevo y abre el proyecto en el antiguo, como antes.
Un detalle de la comparación importaba más de lo que parece. La comprobación se ejecuta con la cuenta de administrador, y git se niega a leer un repositorio que pertenece a otro usuario. No imprimió nada en ninguno de los dos lados, y “nada” coincidió con “nada”, así que la comprobación pasó sin comparar ningún historial. Le indicamos a git que confiara en el directorio y añadimos una prueba para que eso no vuelva a colarse.
Qué salió mal el primer día
El primer día en producción, empaquetar un proyecto superó un tiempo límite de cinco minutos de comando, dentro del despertar. La persona propietaria esperó siete minutos a que se abriera su espacio de trabajo. Y como el traslado había fallado, el proyecto seguía pequeño, así que la siguiente apertura habría intentado de nuevo y la habría hecho esperar otra vez.
Una migración que hace esperar a alguien al abrir su propio proyecto es un mal negocio. El sentido de hacerla al despertar era que nadie se diera cuenta.
Segundo intento: un presupuesto estricto
Ese mismo día cambiamos cuatro cosas:
- Un minuto para todo el traslado. Cada paso —comprobar el tamaño, empaquetar, crear el espacio nuevo, copiar, desempaquetar, comparar— comparte un único presupuesto de 60 segundos. Cuando se agota, el proyecto se abre en el espacio antiguo.
- Detener el trabajo, no solo la espera. Rendirse de nuestro lado no basta si el archivado sigue ejecutándose dentro del espacio que la persona propietaria está a punto de usar. Ahora cada comando de archivado se mata dentro del propio espacio poco antes de que termine el presupuesto. Si el espacio nuevo llega después de que nos hayamos rendido, se descarta.
- No hacer esperar al propietario por la limpieza. Borrar el archivo temporal ahora ocurre en segundo plano.
- No reintentar en cada apertura. Un proyecto que no pudo moverse se deja en paz durante 24 horas, así que un fallo cuesta como mucho un retraso al día, no uno por apertura.
Tercer intento: sacarlo del despertar
Eso limitó el peor caso a un minuto. Pero un minuto sigue siendo un minuto, y nos dimos cuenta de que el traslado no necesitaba estar en el camino de nadie.
Ya no se crea ningún espacio de 1 GB, así que esto no es un proceso continuo: es un trabajo puntual con una lista fija de espacios. Hacerlo dentro del despertar significaba que una persona real pagaba cada traslado lento, y la única forma de saber que un espacio no se movería era que alguien acabara de esperar por él.
Así que quitamos el traslado del despertar por completo. Abrir un proyecto hace lo mismo que antes. Los espacios pequeños que quedan se tratan como un lote supervisado: nadie espera por él, y un espacio que no se pueda mover aparece en el informe del lote, donde podemos revisarlo, en lugar de aparecer delante de la persona propietaria.
Lo que aprendimos
- Redimensionar no siempre es posible. Cuando una plataforma fija un tamaño al crear, subir el valor por defecto solo ayuda a lo nuevo. Planifica para lo antiguo.
- “Nadie lo está usando todavía” sigue significando que alguien espera. El trabajo que se hace al entrar en un producto es trabajo que una persona observa.
- Pon un presupuesto a cualquier cosa que esté en el camino de un usuario, y detén el trabajo cuando se agote. Dar tiempo de espera de nuestro lado mientras un comando sigue corriendo en otra parte solo traslada el problema.
- Una migración puntual pertenece a un trabajo puntual. Esconderla dentro de las acciones cotidianas la hace más barata de escribir y más cara de ejecutar.
- Prueba tus comprobaciones de seguridad. Una comparación que no compara nada se ve exactamente igual que una que pasó.
Si construyes en Mythex, no tienes que hacer nada: el objetivo es simplemente que se queden sin memoria menos espacios de trabajo, con la apertura de proyectos tan rápida como antes. Cómo se pausan y se despiertan los espacios de trabajo está explicado en la documentación, en espacio de trabajo privado. Para otra historia de falta de memoria, consulta el fallo de memoria oculto en una etiqueta de progreso.