sage/stop.sh
yumoqing 3de5a1ce91 feat: multi-process architecture with independent backend processes
- Extract backend_accounting from llmage cleanupctx to independent process
- Add bin/backend_accounting.py for standalone LLM billing loop
- Rewrite start.sh with two-phase startup:
  1. Independent backend programs (run once)
  2. Sage Web workers (SO_REUSEPORT on same port)
- Rewrite stop.sh to handle both workers and backend processes
- Add .gitignore for build artifacts and runtime files

Architecture:
- CPU core detection for worker count
- All workers share port 9180 via SO_REUSEPORT
- Backend processes tracked in sage_backend.pid
- Workers tracked in sage.pid
2026-05-17 00:11:53 +08:00

116 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
# Sage Web Application Stop Script
# 停止所有 Web Workers 和独立后台程序
set -e
# 切换到脚本所在目录
cd "$(dirname "$0")"
WORKDIR="$(pwd)"
PIDFILE="$WORKDIR/sage.pid"
BINPIDFILE="$WORKDIR/sage_backend.pid"
echo "========================================="
echo "停止 Sage Web Application"
echo "========================================="
# =========================================
# 步骤 1: 停止 Web Workers
# =========================================
echo ""
echo "--- 停止 Web Workers ---"
if [ -f "$PIDFILE" ]; then
echo "读取 Worker PID 文件..."
while IFS= read -r pid || [ -n "$pid" ]; do
pid=$(echo "$pid" | tr -d '[:space:]')
[ -z "$pid" ] && continue
if kill -0 "$pid" 2>/dev/null; then
echo "正在停止 Worker (PID: $pid) ..."
kill "$pid" 2>/dev/null || true
else
echo "Worker (PID: $pid) 已不在运行"
fi
done < "$PIDFILE"
# 等待进程退出
echo "等待服务关闭..."
for i in $(seq 1 10); do
all_stopped=true
while IFS= read -r pid || [ -n "$pid" ]; do
pid=$(echo "$pid" | tr -d '[:space:]')
[ -z "$pid" ] && continue
if kill -0 "$pid" 2>/dev/null; then
all_stopped=false
break
fi
done < "$PIDFILE"
if $all_stopped; then
echo "所有 Worker 已停止 (用时 ${i}s)"
break
fi
sleep 1
done
# 强制杀死仍在运行的进程
while IFS= read -r pid || [ -n "$pid" ]; do
pid=$(echo "$pid" | tr -d '[:space:]')
[ -z "$pid" ] && continue
if kill -0 "$pid" 2>/dev/null; then
echo "强制停止 Worker (PID: $pid)"
kill -9 "$pid" 2>/dev/null || true
fi
done < "$PIDFILE"
# 清理 PID 文件
rm -f "$PIDFILE"
else
echo "未找到 Worker PID 文件 ($PIDFILE)"
fi
# =========================================
# 步骤 2: 停止独立后台程序
# =========================================
echo ""
echo "--- 停止独立后台程序 ---"
if [ -f "$BINPIDFILE" ]; then
echo "读取后台程序 PID 文件..."
while IFS= read -r line || [ -n "$line" ]; do
line=$(echo "$line" | tr -d '[:space:]')
[ -z "$line" ] && continue
# 格式: name:pid
name="${line%%:*}"
pid="${line##*:}"
if kill -0 "$pid" 2>/dev/null; then
echo "正在停止 $name (PID: $pid) ..."
kill "$pid" 2>/dev/null || true
sleep 1
if kill -0 "$pid" 2>/dev/null; then
echo "强制停止 $name (PID: $pid)"
kill -9 "$pid" 2>/dev/null || true
fi
echo " -> $name 已停止"
else
echo "$name (PID: $pid) 已不在运行"
fi
done < "$BINPIDFILE"
# 清理 PID 文件
rm -f "$BINPIDFILE"
else
echo "未找到后台程序 PID 文件 ($BINPIDFILE)"
fi
echo ""
echo "========================================="
echo "所有服务已停止"
echo "========================================="