gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1506Shell 186Rust 107Markdown 983639 Definiciones

Etapa G (granja): concilia la colisión de concurrencia — reintento serial de fallos por dep compartida

build-farm.sh asumía 'sin colisión entre recetas distintas', falso para deps transitivas
compartidas no selladas: dos consumidores (p.ej. libadwaita/gtksourceview) construyen gtk4 a
la vez en el mismo sources/gtk4-<sha>/output ⇒ 'Some other Meson process is already using this
build directory'. Fase 1b: tras el pool paralelo, reintenta EN SERIE los fallos con firma de
colisión — la dep ya la selló el ganador ⇒ cache-hit y compila. Un pase basta (cada build
arrastra sus deps). Sólo reintenta colisiones, no MSRV/dep-faltante reales.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

823c7e1171bdd339a7263205856fb6788bf03649 · por sergio · (hace 3 meses) · padre a3732fc96 · ver el árbol en este commit

Delta semántico

Ninguna definición cambió: el cambio es de texto, documentación o datos.

1 archivos · +23 −2

diff --git a/scripts/build-farm.sh b/scripts/build-farm.sh
index 6819cb48..c5d57b88 100755
--- a/scripts/build-farm.sh
+++ b/scripts/build-farm.sh
@@ -36,8 +36,10 @@ n_total=$(printf '%s\n' "$queue" | wc -l | tr -d ' ')
 echo "==> GRANJA: $n_total recetas en $QUEUE, $JOBS workers en paralelo"
 
 # ── Fase 1: BUILD en paralelo. Cada worker construye una receta y deja su status (.ok con hash | .fail
-# con motivo). El store sella atómico y cada build usa sources/<name>-<sha> + out/<hash>-<name> propios
-# ⇒ sin colisión entre recetas distintas. `xargs -P` es el pool.
+# con motivo). El store sella atómico y cada RECETA usa sources/<name>-<sha> + out/<hash>-<name> propios.
+# CAVEAT: dos recetas DISTINTAS que comparten una dep transitiva NO sellada (p.ej. gtk4 bajo libadwaita
+# y gtksourceview) la construyen en el MISMO sources/<dep>-<sha>/output ⇒ chocan (meson/tar). Eso lo
+# concilia la Fase 1b (reintento serial). `xargs -P` es el pool.
 printf '%s\n' "$queue" | xargs -P"$JOBS" -I '{}' sh -c '
   f="$1"; n=$(basename "$f" .toml); log="'"$FARM"'/log/$n.log"
   H=$("'"$HAMMER"'" --store "'"$STORE"'" build "$f" 2>"$log" | tail -1 || true)
@@ -49,6 +51,25 @@ printf '%s\n' "$queue" | xargs -P"$JOBS" -I '{}' sh -c '
   fi
 ' _ '{}'
 
+# ── Fase 1b: REINTENTO SERIAL de fallos por COLISIÓN de concurrencia. El pool paralelo puede hacer que
+# dos recetas construyan la MISMA dep transitiva compartida (gtk4/cairo/pango bajo varios consumidores)
+# a la vez en sources/<dep>-<sha>/output ⇒ meson/tar chocan ("Some other Meson process is already using
+# this build directory", "Directory not empty", "No such file"). Tras la Fase 1 la dep ya la selló el
+# ganador de la carrera ⇒ reconstruir el fallo EN SERIE ahora cache-hitea la dep y compila sin colisión.
+# Un solo pase basta: cada `hammer build` arrastra sus deps, así que aunque el orden no sea topológico,
+# la dep se construye/sella dentro del propio reintento. Sólo se reintenta lo que tiene FIRMA de colisión
+# (no MSRV/dep-faltante reales, que re-fallarían y sólo gastarían tiempo).
+for s in "$FARM"/status/*.fail; do
+  [ -f "$s" ] || continue
+  n=$(basename "$s" .fail); log="$FARM/log/$n.log"; f="$QUEUE/$n.toml"
+  [ -f "$f" ] || continue
+  grep -qiE "Some other Meson process|already using this build directory|Directory not empty|No such file or directory|gdkconfig\.h" "$log" 2>/dev/null || continue
+  H=$("$HAMMER" --store "$STORE" build "$f" 2>"$log" | tail -1 || true)
+  if [ "${H#b3:}" != "$H" ] && [ -n "$H" ]; then
+    rm -f "$s"; echo "$H" > "$FARM/status/$n.ok"; printf "  ✓ (reintento serial) %-18s %s\n" "$n" "$H"
+  fi
+done
+
 # ── Fase 2: PROMOTE + PUBLISH en serie (índice del repo = recurso mutable compartido).
 ok=$(ls "$FARM"/status/*.ok 2>/dev/null | wc -l | tr -d ' ')
 fail=$(ls "$FARM"/status/*.fail 2>/dev/null | wc -l | tr -d ' ')