From b6a35bc2bce838a4ca0d495ecf854d2db47e2841 Mon Sep 17 00:00:00 2001 From: Sergio Date: Sun, 6 Sep 2026 03:30:25 +0000 Subject: [PATCH] worker-loop: que el watchdog no se lleve el post-mortem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El watchdog barre work/sources/* cada 180 s con un suelo de 2 minutos, así que el árbol de una receta que ACABA DE FALLAR se destruye antes de que nadie lo mire. Medido hoy: waterfox murió a las 03:20:15 tras 36 minutos y 23.980 pasos, enlazando libxul.so con un `collect2: error: ld returned 1 exit status` SIN mensaje del linker delante — o sea justo el caso en que hace falta el objdir. A las 03:22 work/sources/ estaba vacío. Reproducirlo cuesta otros 36 minutos. Lo que más molesta es que la doctrina ya estaba escrita en el repo, en dos sitios, y este watchdog la contradecía sin que nadie lo notara: campana-deuda.sh:138 «NO se poda tras un ✗: el árbol de una receta que falló es el post-mortem» poda-fuentes.sh suelo de 24 h, «deja el post-mortem del día» No se arregla subiendo el suelo a secas: este watchdog existe para que una tanda Go no llene el disco vendoreando, y ahí los minutos importan de verdad (80 G en una tanda, con el I/O-wait disparando el load). Se arregla siendo agresivo SÓLO cuando el recurso escasea: con el disco por debajo de DISK_HIGH el suelo pasa a SUELO_FRIO_MIN (120 min por defecto, configurable); en cuanto el disco aprieta vuelve a los 2 minutos de siempre. Un árbol frío con disco al 37% no le hace daño a nadie. Probado en los dos sentidos: árbol de 5 min -> se borra con suelo 2, protegido con suelo 120; árbol de 3 h -> se borra con los dos (ya no es post-mortem). Ojo al leerlo: `df --output=pcent` da el porcentaje USADO, no el libre. La primera versión de este parche llamaba `libre` a esa variable. --- scripts/farm/farm-worker-loop.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/scripts/farm/farm-worker-loop.sh b/scripts/farm/farm-worker-loop.sh index 60d5d200..27e77310 100755 --- a/scripts/farm/farm-worker-loop.sh +++ b/scripts/farm/farm-worker-loop.sh @@ -36,6 +36,9 @@ mkdir -p "$HAMMER_DIR/work" # pisa un vendor en curso, esa receta reintenta el próximo ciclo (cache-hit el resto). Sin esto, una # tanda Go grande llena el disco de 80G y el I/O-wait dispara el load (cuello real, no CPU/RAM). DISK_HIGH="${DISK_HIGH:-82}" +# Cuántos minutos se le respetan a un árbol EN FRÍO cuando el disco NO está apretado. Es la ventana +# de post-mortem: por debajo de esto, un fallo se lleva su propia evidencia (ver protección 4). +SUELO_FRIO_MIN="${SUELO_FRIO_MIN:-120}" ( while :; do sleep 180 @@ -56,7 +59,23 @@ DISK_HIGH="${DISK_HIGH:-82}" # que NO coincide con la receta en vuelo ⇒ protecciones 1 y 2 no la cubren. Sin esto, el rm -rf # compite con el tar y deja el árbol a medias ("Cannot mkdir" / luego "Directory not empty" para # siempre). Un árbol en frío (extracción ya fallida/terminada) queda purgable ⇒ se re-extrae limpio. - [ -n "$(find "$dd" -mmin -2 -print -quit 2>/dev/null)" ] && continue + # Protección 4: EL POST-MORTEM (2026-09-06). Con el suelo en 2 min, el árbol de una receta que + # ACABA DE FALLAR se barre antes de que nadie lo mire: `waterfox` murió a las 03:20:15 tras 36 + # min y 23.980 pasos, enlazando `libxul.so`, y a las 03:22 `work/sources/` estaba VACÍO. El + # objdir con la evidencia se fue con él y reproducirlo cuesta otros 36 min. + # + # El repo ya tiene la doctrina escrita en otros dos sitios y este watchdog la contradecía: + # `campana-deuda.sh` dice «NO se poda tras un ✗: el árbol de una receta que falló es el + # post-mortem», y `poda-fuentes.sh` usa un suelo de 24 h justamente para «dejar el post-mortem + # del día». + # + # No se arregla subiendo el suelo a secas: este watchdog existe para que una tanda Go no llene + # el disco vendoreando, y ahí los minutos importan. Se arregla siendo agresivo SÓLO cuando el + # recurso escasea de verdad — con disco holgado, un árbol frío no le hace daño a nadie. + usado=$(df --output=pcent "$HAMMER_DIR" 2>/dev/null | tr -dc '0-9') # pcent = USADO, no libre + suelo=$SUELO_FRIO_MIN + [ -n "$usado" ] && [ "$usado" -ge "$DISK_HIGH" ] && suelo=2 # disco apretado ⇒ como antes + [ -n "$(find "$dd" -mmin -"$suelo" -print -quit 2>/dev/null)" ] && continue rm -rf "$dd" done use=$(df --output=pcent "$HAMMER_DIR" 2>/dev/null | tr -dc '0-9')