3d55f189c0
Iter 22. Cierra el set de hoy: future-me (o cualquier nuevo collab)
levanta el escenario completo con un comando.
crates/apps/brahman-demo/ con 3 binarios:
- brahman-demo-broker: Server::bind standalone con Broker. Reemplaza
a ente-zero para demos (ente-zero es PID 1 con kernel surface,
child subreaper, bus, brain, audit — overkill).
- brahman-demo-producer: Card con flow.output[demo-stream:json].
- brahman-demo-consumer: Card con flow.input[demo-feed:json] —
mismo type → matchea con producer.
Env vars en los 3: BRAHMAN_INIT_SOCKET, BRAHMAN_BROKER_CONTEXT,
BRAHMAN_DEMO_LABEL/FLOW/TYPE, RUST_LOG.
scripts/bootstrap-demo.sh:
- Modes: all (default) / broker / only.
- Cleanup-safe: trap mata todos los PIDs spawneados (SIGTERM grace
+ SIGKILL fallback) y borra el socket.
- Espera al socket antes de spawnear (evita ENOENT en handshake).
- Logs separados por proceso bajo $BRAHMAN_DEMO_LOG_DIR.
Smoke end-to-end (sin DISPLAY): consumer recibe MatchEvent
{ Available, demo-feed ← demo-stream, via: Exact, pinned: false }
automáticamente cuando entra el producer. Match fluye por el push
channel del broker.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
147 lines
5.1 KiB
Bash
Executable File
147 lines
5.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# bootstrap-demo.sh — arranca un escenario reproducible de brahman:
|
|
# broker standalone + 1 producer demo + 1 consumer demo (mismo flow
|
|
# tipo, así el broker computa un Match y el broker-explorer lo ve en
|
|
# sesiones + timeline) + abre los 4 explorers GPUI.
|
|
#
|
|
# Uso:
|
|
# scripts/bootstrap-demo.sh # default: abre todos
|
|
# scripts/bootstrap-demo.sh broker # sólo broker + producers
|
|
# scripts/bootstrap-demo.sh broker only # ni siquiera producers
|
|
#
|
|
# Limpieza: Ctrl-C dispara `cleanup` que mata todos los procesos
|
|
# spawneados por este script (broker, producers, explorers). Logs
|
|
# de cada uno quedan bajo $LOG_DIR (default /tmp/brahman-demo) para
|
|
# que después se puedan revisar — el script los borra cuando se
|
|
# vuelve a invocar (no acumula).
|
|
#
|
|
# Asume `cargo build --workspace` ya hecho. Si no, descomentá la
|
|
# línea `cargo build` debajo (toma minutos en cold cache).
|
|
|
|
set -euo pipefail
|
|
|
|
LOG_DIR="${BRAHMAN_DEMO_LOG_DIR:-/tmp/brahman-demo}"
|
|
SOCKET="${BRAHMAN_INIT_SOCKET:-/tmp/brahman-init.sock}"
|
|
MODE="${1:-all}"
|
|
|
|
# Path resolution: si el script vive en repo/scripts/, el repo es el padre.
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
cd "$REPO_DIR"
|
|
|
|
# Limpieza de logs viejos. Mantenemos el dir, sólo vaciamos.
|
|
mkdir -p "$LOG_DIR"
|
|
rm -f "$LOG_DIR"/*.log
|
|
|
|
# Track de PIDs spawneados para que el trap los mate todos.
|
|
PIDS=()
|
|
|
|
cleanup() {
|
|
echo
|
|
echo "[bootstrap-demo] cleanup — matando ${#PIDS[@]} procesos"
|
|
for pid in "${PIDS[@]}"; do
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
kill "$pid" 2>/dev/null || true
|
|
fi
|
|
done
|
|
# Espera breve para que cierren cleanly antes de SIGKILL.
|
|
sleep 1
|
|
for pid in "${PIDS[@]}"; do
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
kill -9 "$pid" 2>/dev/null || true
|
|
fi
|
|
done
|
|
# El socket lo limpia el broker al hacer Drop, pero defendemos
|
|
# contra crashes.
|
|
rm -f "$SOCKET"
|
|
echo "[bootstrap-demo] terminado. logs: $LOG_DIR"
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
|
|
# Si querés re-build automático, descomentá:
|
|
# echo "[bootstrap-demo] cargo build (puede tomar minutos en cold cache)"
|
|
# cargo build -p brahman-demo -p brahman-broker-explorer \
|
|
# -p nakui-explorer -p nouser-explorer -p minga-explorer
|
|
|
|
# 1. Broker. Bind del socket. Si ya hay un proceso ocupando el
|
|
# socket, esto falla rápido — el cleanup del trap se encarga.
|
|
echo "[bootstrap-demo] arrancando broker → $SOCKET"
|
|
BRAHMAN_INIT_SOCKET="$SOCKET" \
|
|
cargo run --quiet -p brahman-demo --bin brahman-demo-broker \
|
|
> "$LOG_DIR/broker.log" 2>&1 &
|
|
PIDS+=($!)
|
|
|
|
# Esperar a que el socket aparezca (el broker hace bind tras boot).
|
|
# Sin esto, los siguientes connects rebotan ENOENT.
|
|
for _ in $(seq 1 50); do
|
|
[ -S "$SOCKET" ] && break
|
|
sleep 0.1
|
|
done
|
|
if [ ! -S "$SOCKET" ]; then
|
|
echo "[bootstrap-demo] ERROR: broker no creó el socket en 5s — ver $LOG_DIR/broker.log"
|
|
exit 1
|
|
fi
|
|
echo "[bootstrap-demo] broker UP (pid ${PIDS[-1]})"
|
|
|
|
# 2. Producer + consumer (a menos que MODE=only).
|
|
if [ "$MODE" != "only" ]; then
|
|
echo "[bootstrap-demo] arrancando producer (flow demo-stream/json)"
|
|
BRAHMAN_INIT_SOCKET="$SOCKET" \
|
|
BRAHMAN_DEMO_LABEL=demo-producer \
|
|
BRAHMAN_DEMO_FLOW=demo-stream \
|
|
BRAHMAN_DEMO_TYPE=json \
|
|
cargo run --quiet -p brahman-demo --bin brahman-demo-producer \
|
|
> "$LOG_DIR/producer.log" 2>&1 &
|
|
PIDS+=($!)
|
|
|
|
echo "[bootstrap-demo] arrancando consumer (flow demo-feed/json — matchea con producer)"
|
|
BRAHMAN_INIT_SOCKET="$SOCKET" \
|
|
BRAHMAN_DEMO_LABEL=demo-consumer \
|
|
BRAHMAN_DEMO_FLOW=demo-feed \
|
|
BRAHMAN_DEMO_TYPE=json \
|
|
cargo run --quiet -p brahman-demo --bin brahman-demo-consumer \
|
|
> "$LOG_DIR/consumer.log" 2>&1 &
|
|
PIDS+=($!)
|
|
|
|
# Pequeño grace para que los handshakes completen antes que los
|
|
# explorers se conecten (sino el primer ListSessions devuelve algo
|
|
# transitorio sin las sesiones demo).
|
|
sleep 1
|
|
fi
|
|
|
|
# 3. Explorers GPUI (a menos que MODE=broker).
|
|
if [ "$MODE" != "broker" ] && [ "$MODE" != "only" ]; then
|
|
echo "[bootstrap-demo] abriendo brahman-broker-explorer"
|
|
BRAHMAN_INIT_SOCKET="$SOCKET" \
|
|
cargo run --quiet -p brahman-broker-explorer \
|
|
> "$LOG_DIR/broker-explorer.log" 2>&1 &
|
|
PIDS+=($!)
|
|
|
|
echo "[bootstrap-demo] abriendo nouser-explorer (descubrirá vía broker si nouserd corre)"
|
|
BRAHMAN_INIT_SOCKET="$SOCKET" \
|
|
cargo run --quiet -p nouser-explorer \
|
|
> "$LOG_DIR/nouser-explorer.log" 2>&1 &
|
|
PIDS+=($!)
|
|
|
|
# nakui-explorer y minga-explorer son standalone (no usan broker)
|
|
# — los abrimos igual para tener el dashboard completo. Apuntan a
|
|
# paths default; si no hay nakui-events.jsonl o repo minga, sólo
|
|
# mostrarán el banner "esperando…".
|
|
echo "[bootstrap-demo] abriendo nakui-explorer (standalone)"
|
|
cargo run --quiet -p nakui-explorer > "$LOG_DIR/nakui-explorer.log" 2>&1 &
|
|
PIDS+=($!)
|
|
|
|
echo "[bootstrap-demo] abriendo minga-explorer (standalone)"
|
|
cargo run --quiet -p minga-explorer > "$LOG_DIR/minga-explorer.log" 2>&1 &
|
|
PIDS+=($!)
|
|
fi
|
|
|
|
echo
|
|
echo "[bootstrap-demo] todo arriba — Ctrl-C para parar todo"
|
|
echo "[bootstrap-demo] logs en $LOG_DIR/"
|
|
echo
|
|
|
|
# Wait sobre el broker: si éste cae, todo el demo deja de tener
|
|
# sentido. El trap se encarga del resto.
|
|
wait "${PIDS[0]}"
|