2026-07-10 12:54:45 +00:00
|
|
|
|
#!/usr/bin/env bash
|
2026-07-13 01:15:30 +00:00
|
|
|
|
# 停止 gateway + worker + web(不碰 infra / 資料)
|
|
|
|
|
|
# 策略:pidfile → cmdline 比對 → 佔用埠的 process → 等埠釋放
|
2026-07-10 12:54:45 +00:00
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
# shellcheck source=_common.sh
|
|
|
|
|
|
source "$(cd "$(dirname "$0")" && pwd)/_common.sh"
|
|
|
|
|
|
|
|
|
|
|
|
log "stopping apps…"
|
2026-07-13 01:15:30 +00:00
|
|
|
|
load_env 2>/dev/null || true
|
|
|
|
|
|
GATEWAY_PORT="${GATEWAY_PORT:-8888}"
|
|
|
|
|
|
WEB_PORT="${WEB_PORT:-5173}"
|
|
|
|
|
|
STUCK_PIDS=""
|
2026-07-10 12:54:45 +00:00
|
|
|
|
|
2026-07-13 01:15:30 +00:00
|
|
|
|
stop_pidfile() {
|
|
|
|
|
|
local name="$1"
|
|
|
|
|
|
local file="$2"
|
|
|
|
|
|
if [[ ! -f "$file" ]]; then
|
|
|
|
|
|
return 0
|
2026-07-10 12:54:45 +00:00
|
|
|
|
fi
|
2026-07-13 01:15:30 +00:00
|
|
|
|
local pid
|
|
|
|
|
|
pid="$(cat "$file" 2>/dev/null || true)"
|
|
|
|
|
|
rm -f "$file"
|
|
|
|
|
|
if [[ -n "$pid" ]]; then
|
|
|
|
|
|
kill_pid "$pid" "$name" || true
|
|
|
|
|
|
fi
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 1) 正式 pidfile
|
|
|
|
|
|
stop_pidfile gateway "$PID_GATEWAY"
|
|
|
|
|
|
stop_pidfile worker "$PID_WORKER"
|
|
|
|
|
|
stop_pidfile web "$PID_WEB"
|
2026-07-10 12:54:45 +00:00
|
|
|
|
|
2026-07-13 01:15:30 +00:00
|
|
|
|
# 2) 掃殘留 process(手動 nohup / 舊 pidfile 遺失)
|
|
|
|
|
|
for p in $(pids_by_cmdline_substr "bin/gateway" "gateway.yaml"); do
|
|
|
|
|
|
kill_pid "$p" "gateway(cmd)" || true
|
|
|
|
|
|
done
|
|
|
|
|
|
for p in $(pids_by_cmdline_substr "bin/worker" "gateway.yaml"); do
|
|
|
|
|
|
kill_pid "$p" "worker(cmd)" || true
|
|
|
|
|
|
done
|
|
|
|
|
|
# 本 repo 的 vite(node …/apps/web/…/vite 或 --port WEB_PORT)
|
|
|
|
|
|
for p in $(pids_by_cmdline_substr "vite" ""); do
|
|
|
|
|
|
cmd=""
|
|
|
|
|
|
if [[ -r "/proc/$p/cmdline" ]]; then
|
|
|
|
|
|
cmd="$(tr '\0' ' ' <"/proc/$p/cmdline" 2>/dev/null || true)"
|
|
|
|
|
|
fi
|
|
|
|
|
|
if [[ "$cmd" == *"$WEB_DIR"* || "$cmd" == *"/apps/web/"* || "$cmd" == *"--port ${WEB_PORT}"* || "$cmd" == *"--port=${WEB_PORT}"* ]]; then
|
|
|
|
|
|
kill_pid "$p" "vite(cmd)" || true
|
|
|
|
|
|
fi
|
|
|
|
|
|
done
|
|
|
|
|
|
# npm run dev 父行程
|
|
|
|
|
|
for p in $(pids_by_cmdline_substr "npm run dev" ""); do
|
|
|
|
|
|
cmd=""
|
|
|
|
|
|
if [[ -r "/proc/$p/cmdline" ]]; then
|
|
|
|
|
|
cmd="$(tr '\0' ' ' <"/proc/$p/cmdline" 2>/dev/null || true)"
|
|
|
|
|
|
fi
|
|
|
|
|
|
# cwd 難取;若 cmdline 含 web path 才殺
|
|
|
|
|
|
if [[ "$cmd" == *"$WEB_DIR"* || "$cmd" == *"/apps/web"* ]]; then
|
|
|
|
|
|
kill_pid "$p" "npm-dev(cmd)" || true
|
2026-07-10 12:54:45 +00:00
|
|
|
|
fi
|
2026-07-13 01:15:30 +00:00
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
# 3) 依埠清
|
|
|
|
|
|
kill_port "$GATEWAY_PORT" || true
|
|
|
|
|
|
kill_port "$WEB_PORT" || true
|
|
|
|
|
|
kill_port 5174 || true
|
|
|
|
|
|
|
|
|
|
|
|
# 4) 等埠空出
|
|
|
|
|
|
if ! wait_port_free "$GATEWAY_PORT" 8; then
|
|
|
|
|
|
err "埠 :${GATEWAY_PORT} 仍 LISTEN"
|
|
|
|
|
|
fi
|
|
|
|
|
|
if ! wait_port_free "$WEB_PORT" 4; then
|
|
|
|
|
|
err "埠 :${WEB_PORT} 仍 LISTEN"
|
2026-07-10 12:54:45 +00:00
|
|
|
|
fi
|
|
|
|
|
|
|
2026-07-13 01:15:30 +00:00
|
|
|
|
print_stuck_hint
|
|
|
|
|
|
|
|
|
|
|
|
if port_in_use "$GATEWAY_PORT" || port_in_use "$WEB_PORT"; then
|
|
|
|
|
|
log "apps stop incomplete (ports still busy)"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
2026-07-10 12:54:45 +00:00
|
|
|
|
|
|
|
|
|
|
log "apps stopped"
|
2026-07-13 01:15:30 +00:00
|
|
|
|
exit 0
|