-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlatency-ui.sh
More file actions
executable file
·153 lines (135 loc) · 4.25 KB
/
Copy pathlatency-ui.sh
File metadata and controls
executable file
·153 lines (135 loc) · 4.25 KB
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env bash
# Manage the Audio Latency Analyzer web UI.
#
# Usage:
# ./latency-ui.sh start Start the server in the background
# ./latency-ui.sh stop Stop the running server
# ./latency-ui.sh restart Stop then start
# ./latency-ui.sh status Show running state
# ./latency-ui.sh logs Tail the log (Ctrl-C to exit)
#
# Environment variables (all optional):
# LATENCY_UI_HOST Host to bind (default: 127.0.0.1)
# LATENCY_UI_PORT Port to listen on (default: 8000)
# LATENCY_UI_LOG Log file path (default: ./latency-ui.log)
# LATENCY_UI_PID PID file path (default: ./latency-ui.pid)
# LATENCY_UI_BIN Path to latency-ui binary (default: latency-ui on PATH)
# LATENCY_UI_PROXY_PREFIX URL prefix when served behind a reverse proxy
# (e.g. "/latency"). Default: "" (served at root).
# LATENCY_UI_CACHE_DIR Transcoded audio cache directory
# LATENCY_UI_CACHE_MAX_AGE_HOURS Cache eviction age in hours (default 24)
set -euo pipefail
HOST="${LATENCY_UI_HOST:-127.0.0.1}"
PORT="${LATENCY_UI_PORT:-8000}"
LOG_FILE="${LATENCY_UI_LOG:-./latency-ui.log}"
PID_FILE="${LATENCY_UI_PID:-./latency-ui.pid}"
BIN="${LATENCY_UI_BIN:-latency-ui}"
is_running() {
[[ -f "$PID_FILE" ]] || return 1
local pid
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
[[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null
}
# Echo "HOST:PORT" for a running server, parsed from its actual command
# line (/proc/PID/cmdline) so status reflects how the process was really
# started — the current shell's env vars may differ from start time.
# Falls back to the configured HOST/PORT if the cmdline isn't readable.
running_host_port() {
local pid="$1"
local host="$HOST" port="$PORT"
if [[ -r "/proc/$pid/cmdline" ]]; then
local args
args="$(tr '\0' ' ' < "/proc/$pid/cmdline")"
[[ "$args" =~ --host[[:space:]]+([^[:space:]]+) ]] && host="${BASH_REMATCH[1]}"
[[ "$args" =~ --port[[:space:]]+([^[:space:]]+) ]] && port="${BASH_REMATCH[1]}"
fi
echo "$host:$port"
}
cmd_start() {
if is_running; then
echo "Already running (pid $(cat "$PID_FILE"))"
return 0
fi
if ! command -v "$BIN" >/dev/null 2>&1; then
echo "Error: '$BIN' not found on PATH. Install with: pip install .[web]" >&2
exit 1
fi
echo "Starting latency-ui on $HOST:$PORT (log: $LOG_FILE)"
nohup "$BIN" --host "$HOST" --port "$PORT" >> "$LOG_FILE" 2>&1 &
local pid=$!
# Detach from the job table so bash won't try to wait/reap us later
disown "$pid" 2>/dev/null || true
echo "$pid" > "$PID_FILE"
# Watch the process for up to 8 seconds. Uvicorn takes ~4-5 seconds to
# fail-and-exit when the port is already bound by another process, so
# our window needs to cover that. If the process exits during this
# window, it failed — report it. If it survives, it started.
local deadline=$((SECONDS + 8))
while (( SECONDS < deadline )); do
if ! kill -0 "$pid" 2>/dev/null; then
rm -f "$PID_FILE"
echo "Failed to start — last log lines:" >&2
tail -n 20 "$LOG_FILE" >&2 2>/dev/null || true
exit 1
fi
sleep 0.25
done
echo "Started (pid $pid)"
}
cmd_stop() {
if ! is_running; then
echo "Not running"
rm -f "$PID_FILE"
return 0
fi
local pid
pid="$(cat "$PID_FILE")"
echo "Stopping pid $pid"
kill "$pid"
# Wait up to 10s for graceful shutdown
for _ in $(seq 1 20); do
kill -0 "$pid" 2>/dev/null || break
sleep 0.5
done
if kill -0 "$pid" 2>/dev/null; then
echo "Graceful stop timed out; sending SIGKILL"
kill -9 "$pid" 2>/dev/null || true
fi
rm -f "$PID_FILE"
echo "Stopped"
}
cmd_restart() {
cmd_stop
cmd_start
}
cmd_status() {
if is_running; then
local pid
pid="$(cat "$PID_FILE")"
echo "Running (pid $pid) on $(running_host_port "$pid")"
echo "Log: $LOG_FILE"
else
echo "Not running"
if [[ -f "$PID_FILE" ]]; then
echo "Stale pid file: $PID_FILE"
fi
fi
}
cmd_logs() {
if [[ ! -f "$LOG_FILE" ]]; then
echo "No log file yet ($LOG_FILE)"
exit 1
fi
tail -n 100 -f "$LOG_FILE"
}
case "${1:-}" in
start) cmd_start ;;
stop) cmd_stop ;;
restart) cmd_restart ;;
status) cmd_status ;;
logs) cmd_logs ;;
*)
echo "Usage: $0 {start|stop|restart|status|logs}" >&2
exit 1
;;
esac