mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-21 12:12:22 +02:00
112 lines
3.8 KiB
Bash
Executable File
112 lines
3.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
if [[ -f "$ROOT_DIR/.env" ]]; then
|
|
set -a
|
|
source "$ROOT_DIR/.env"
|
|
set +a
|
|
fi
|
|
|
|
# Recursively SIGTERM a pid + all of its descendants. We track FRONTEND_PID
|
|
# and BACKEND_PID below, but each of those is a `bash` wrapper that has its
|
|
# own grandchildren (vite, uvicorn, npm). A flat `kill $FRONTEND_PID` leaves
|
|
# the grandchildren alive holding their ports until the OS reaps them
|
|
# minutes later — visible to the user as port-already-in-use the next time
|
|
# they hit the App Builder.
|
|
kill_tree() {
|
|
local pid=$1 sig=${2:-TERM}
|
|
local children
|
|
children=$(pgrep -P "$pid" 2>/dev/null)
|
|
for child in $children; do
|
|
kill_tree "$child" "$sig"
|
|
done
|
|
kill -"$sig" "$pid" 2>/dev/null
|
|
}
|
|
|
|
# Previously this was `kill 0`, which SIGTERMs the entire process group.
|
|
# That's fast but propagates UP into OpenSwarm — when this workspace's
|
|
# cleanup fired on ViewEditor unmount or runtime/stop, it tore down the
|
|
# OpenSwarm dev stack (Terminated: 15) and left port 8324 stuck. Now we
|
|
# only kill our own tracked subtree, which keeps containment without
|
|
# requiring an OS-level session wall.
|
|
cleanup() {
|
|
echo ""
|
|
echo "Shutting down all processes..."
|
|
[[ -n "${FRONTEND_PID:-}" ]] && kill_tree "$FRONTEND_PID" TERM
|
|
[[ -n "${BACKEND_PID:-}" ]] && kill_tree "$BACKEND_PID" TERM
|
|
wait 2>/dev/null
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
if [[ "${BACKEND_PORT}" == "NONE" || -z "${BACKEND_PORT}" || ! -f "$ROOT_DIR/backend/run.sh" ]]; then
|
|
# Frontend-only is the safe default: BACKEND_PORT=NONE (frontend-only app),
|
|
# OR unset/empty (e.g. .env missing — never start a backend that isn't
|
|
# configured), OR there is genuinely no backend/run.sh to run. Without the
|
|
# last two guards an unset BACKEND_PORT fell through to the backend branch
|
|
# and `bash backend/run.sh` died with "No such file or directory", tearing
|
|
# the whole app down before the frontend could show.
|
|
echo "Running frontend only (no backend configured)."
|
|
echo ""
|
|
|
|
bash "$ROOT_DIR/frontend/run.sh" 2>&1 | awk '{printf "\033[32m[frontend]\033[0m %s\n", $0; fflush()}' &
|
|
FRONTEND_PID=$!
|
|
|
|
while true; do
|
|
if ! kill -0 $FRONTEND_PID 2>/dev/null; then
|
|
echo ""
|
|
echo "ERROR: Frontend process exited. Tearing down..."
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
done
|
|
else
|
|
BACKEND_URL="http://localhost:${BACKEND_PORT:-8324}/api/health/check"
|
|
MAX_WAIT=60
|
|
|
|
echo "Starting backend..."
|
|
echo ""
|
|
|
|
bash "$ROOT_DIR/backend/run.sh" 2>&1 | awk '{printf "\033[34m[backend]\033[0m %s\n", $0; fflush()}' &
|
|
BACKEND_PID=$!
|
|
|
|
echo "Waiting for backend to be ready..."
|
|
elapsed=0
|
|
while [ $elapsed -lt $MAX_WAIT ]; do
|
|
if ! kill -0 $BACKEND_PID 2>/dev/null; then
|
|
echo "ERROR: Backend process died before becoming ready. Aborting."
|
|
exit 1
|
|
fi
|
|
if curl -s -o /dev/null -w "%{http_code}" "$BACKEND_URL" 2>/dev/null | grep -q "200"; then
|
|
echo ""
|
|
echo "Backend is ready! Starting frontend..."
|
|
echo ""
|
|
break
|
|
fi
|
|
sleep 1
|
|
elapsed=$((elapsed + 1))
|
|
done
|
|
|
|
if [ $elapsed -ge $MAX_WAIT ]; then
|
|
echo "ERROR: Backend failed to start within ${MAX_WAIT}s. Aborting."
|
|
exit 1
|
|
fi
|
|
|
|
bash "$ROOT_DIR/frontend/run.sh" 2>&1 | awk '{printf "\033[32m[frontend]\033[0m %s\n", $0; fflush()}' &
|
|
FRONTEND_PID=$!
|
|
|
|
while true; do
|
|
if ! kill -0 $BACKEND_PID 2>/dev/null; then
|
|
echo ""
|
|
echo "ERROR: Backend process exited. Tearing down..."
|
|
exit 1
|
|
fi
|
|
if ! kill -0 $FRONTEND_PID 2>/dev/null; then
|
|
echo ""
|
|
echo "ERROR: Frontend process exited. Tearing down..."
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
done
|
|
fi
|