diff --git a/scripts/build-farm.sh b/scripts/build-farm.sh index d60712d0..3e7ad811 100755 --- a/scripts/build-farm.sh +++ b/scripts/build-farm.sh @@ -68,14 +68,26 @@ if [ -s "$SELLADOS" ]; then [ -n "$n" ] || n=$(basename "$f" .toml) H=$("$HAMMER" --store "$STORE" hash "$f" 2>/dev/null | tail -1 | sed 's/^b3://') if [ -n "$H" ] && grep -qx "$H-$n" "$SELLADOS"; then saltadas=$((saltadas+1)); continue; fi - filtrada="$filtrada $f" + # ⚠ SALTO DE LÍNEA Y NO ESPACIO, y esto era un BUG que costó throughput en silencio + # (medido 2026-09-16): más abajo la cola se le pasa a `xargs -I{}`, que trata **una línea = un + # elemento**. Unidas por espacios, N recetas llegaban como UN SOLO argumento: la fase paralela + # fallaba siempre con «No such file» y la fase 1b —el reintento serial— salvaba EXACTAMENTE UNA, + # la última, porque `basename` de esa ristra da el último nombre. O sea que la granja molía + # **una receta por cola y por ciclo** en vez de la cola entera, y el log parecía normal: un ✗ + # seguido de un ✓ (reintento serial). Se vio al encolar `lld21` junto a `rust` y descubrir que + # el ciclo decía «2 recetas» y construía una. + filtrada="$filtrada +$f" done [ "$cerradas" -gt 0 ] && echo " ($cerradas CERRADAS por decisión — ver la cabecera de cada receta)" [ "$saltadas" -gt 0 ] && echo " (saltadas $saltadas ya selladas en el hub — ver la nota del sync unidireccional)" queue="$filtrada" [ -n "$(echo $queue)" ] || { echo "nada que hacer en $QUEUE: todo sellado en el hub"; exit 0; } fi -n_total=$(printf '%s\n' "$queue" | wc -l | tr -d ' ') +# `grep -v` porque el acumulador del filtro arranca con una línea vacía, y una línea vacía es un +# elemento más para `xargs -I{}`: construiría la receta "" y ensuciaría el conteo. +queue=$(printf '%s\n' "$queue" | grep -v '^[[:space:]]*$' || true) +n_total=$(printf '%s\n' "$queue" | grep -c . || true) 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