File size: 4,110 Bytes
88d2f2a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env bash
# PolyglotAlpha β€” start the UI in production mode (W16-C).
#
# Why: `pnpm dev` (Next.js dev server) compiles routes on first access, which
# adds ~30s lag the first time the user clicks "Trigger live demo" and
# navigates to /events/{id}. It also double-renders in React strict mode,
# making SSE-heavy pages feel laggy. The production build pre-compiles every
# route and runs in React production mode β†’ instant navigation.
#
# Usage:
#   scripts/run_prod_ui.sh           # build (incremental) + start on :3001
#   PORT=3002 scripts/run_prod_ui.sh # start on a different port
#   SKIP_BUILD=1 scripts/run_prod_ui.sh  # skip build, just (re)start server
#
# Exits non-zero with a clear message if any step fails.

set -u
set -o pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
UI_DIR="${PROJECT_ROOT}/ui"
LOG_DIR="${PROJECT_ROOT}/logs"
LOG_FILE="${LOG_DIR}/ui.prod.log"
BUILD_LOG="${LOG_DIR}/ui.prod.build.log"

PORT="${PORT:-3001}"
SKIP_BUILD="${SKIP_BUILD:-0}"
READY_TIMEOUT_S="${READY_TIMEOUT_S:-20}"

mkdir -p "${LOG_DIR}"

if [[ ! -d "${UI_DIR}" ]]; then
    echo "FATAL: ui directory not found at ${UI_DIR}" >&2
    exit 2
fi

# ---------------------------------------------------------------------------
# Step 1: kill any existing next dev / next start process on the target port.
# ---------------------------------------------------------------------------
echo "[1/4] Stopping any existing UI processes on port ${PORT} ..."
# Kill parent dev/start wrappers first; child next-server lingers otherwise.
pkill -9 -f "next dev" 2>/dev/null || true
pkill -9 -f "next start" 2>/dev/null || true
# Then anything still listening on the port.
PIDS_ON_PORT="$(lsof -ti:"${PORT}" 2>/dev/null || true)"
if [[ -n "${PIDS_ON_PORT}" ]]; then
    for pid in ${PIDS_ON_PORT}; do
        # Only kill node processes β€” leave browser/proxy listeners alone.
        if ps -p "${pid}" -o command= 2>/dev/null | grep -qE "next|node"; then
            kill -9 "${pid}" 2>/dev/null || true
        fi
    done
fi
sleep 1

# ---------------------------------------------------------------------------
# Step 2: build (incremental if .next cache is present).
# ---------------------------------------------------------------------------
if [[ "${SKIP_BUILD}" == "1" ]]; then
    echo "[2/4] SKIP_BUILD=1 β€” skipping next build."
else
    echo "[2/4] Building (incremental if .next cache is valid) β€” see ${BUILD_LOG}"
    BUILD_START="$(date +%s)"
    ( cd "${UI_DIR}" && pnpm build ) > "${BUILD_LOG}" 2>&1
    BUILD_EXIT=$?
    BUILD_END="$(date +%s)"
    BUILD_SECS=$((BUILD_END - BUILD_START))
    if [[ ${BUILD_EXIT} -ne 0 ]]; then
        echo "FATAL: pnpm build failed (exit ${BUILD_EXIT}, ${BUILD_SECS}s). Last 40 lines:" >&2
        tail -n 40 "${BUILD_LOG}" >&2
        exit ${BUILD_EXIT}
    fi
    echo "    Build OK in ${BUILD_SECS}s."
fi

# ---------------------------------------------------------------------------
# Step 3: start production server in background.
# ---------------------------------------------------------------------------
echo "[3/4] Starting production server on :${PORT} ..."
( cd "${UI_DIR}" && nohup pnpm start -p "${PORT}" > "${LOG_FILE}" 2>&1 & )

# ---------------------------------------------------------------------------
# Step 4: wait for the server to respond on /.
# ---------------------------------------------------------------------------
echo "[4/4] Waiting for http://localhost:${PORT}/ to respond (timeout ${READY_TIMEOUT_S}s) ..."
ELAPSED=0
while [[ ${ELAPSED} -lt ${READY_TIMEOUT_S} ]]; do
    CODE="$(curl -m 2 -o /dev/null -s -w "%{http_code}" "http://localhost:${PORT}/" 2>/dev/null || echo "000")"
    if [[ "${CODE}" == "200" ]]; then
        echo ""
        echo "OK Production UI ready at http://localhost:${PORT}/"
        echo "    logs: ${LOG_FILE}"
        exit 0
    fi
    sleep 1
    ELAPSED=$((ELAPSED + 1))
done

echo "FATAL: server did not respond with 200 within ${READY_TIMEOUT_S}s. Last 30 lines of log:" >&2
tail -n 30 "${LOG_FILE}" >&2
exit 3