fix: harden cross-review task state handling

This commit is contained in:
wren
2026-05-12 11:30:56 +08:00
parent 2ca44f6312
commit 3823c9a2e4
10 changed files with 373 additions and 20 deletions
+138 -16
View File
@@ -4,13 +4,16 @@ PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
FRONTEND_DIR="$PROJECT_DIR/legal-platform-frontend"
BACKEND_DIR="$PROJECT_DIR"
WORKER_SCRIPT="$PROJECT_DIR/scripts/start_worker.sh"
BEAT_SCRIPT="$PROJECT_DIR/scripts/start_beat.sh"
LOG_DIR="$PROJECT_DIR/.codex-run"
BACKEND_PID_FILE="$LOG_DIR/backend.pid"
FRONTEND_PID_FILE="$LOG_DIR/frontend.pid"
WORKER_PID_FILE="$LOG_DIR/worker.pid"
BEAT_PID_FILE="$LOG_DIR/beat.pid"
BACKEND_LOG="$LOG_DIR/backend.log"
FRONTEND_LOG="$LOG_DIR/frontend.log"
WORKER_LOG="$LOG_DIR/worker.log"
BEAT_LOG="$LOG_DIR/beat.log"
RED='\033[0;31m'
GREEN='\033[0;32m'
@@ -113,6 +116,22 @@ pid_command() {
ps -p "$pid" -o args= 2>/dev/null | xargs
}
kill_process_tree() {
local pid=$1
[ -n "$pid" ] || return 0
local children
children=$(pgrep -P "$pid" 2>/dev/null || true)
if [ -n "$children" ]; then
local child
for child in $children; do
kill_process_tree "$child"
done
fi
kill "$pid" 2>/dev/null || true
}
ensure_port_free() {
local name=$1
local port=$2
@@ -153,10 +172,12 @@ start_backend() {
exec "$BACKEND_PYTHON" run.py
) >> "$BACKEND_LOG" 2>&1 &
pid=$!
echo "$pid" > "$BACKEND_PID_FILE"
sleep 2
if pid_alive "$pid"; then
local listening_pid
listening_pid=$(port_pid "$BACKEND_PORT")
if pid_alive "$pid" || [ -n "$listening_pid" ]; then
echo "${listening_pid:-$pid}" > "$BACKEND_PID_FILE"
log_success "后端启动成功 (PID: $pid, 端口: $BACKEND_PORT)"
return 0
fi
@@ -185,10 +206,12 @@ start_frontend() {
exec npm run dev:dev
) >> "$FRONTEND_LOG" 2>&1 &
pid=$!
echo "$pid" > "$FRONTEND_PID_FILE"
sleep 4
if pid_alive "$pid"; then
local listening_pid
listening_pid=$(port_pid "$FRONTEND_DEV_PORT")
if pid_alive "$pid" || [ -n "$listening_pid" ]; then
echo "${listening_pid:-$pid}" > "$FRONTEND_PID_FILE"
log_success "前端启动成功 (PID: $pid, 开发端口: $FRONTEND_DEV_PORT, 访问端口: $FRONTEND_PUBLIC_PORT)"
return 0
fi
@@ -234,29 +257,89 @@ start_worker() {
return 1
}
start_beat() {
cleanup_pid_file "$BEAT_PID_FILE"
local pid
pid=$(service_pid "$BEAT_PID_FILE")
if pid_alive "$pid"; then
log_warn "Beat 已在运行 (PID: $pid)"
return 0
fi
if [ ! -x "$BEAT_SCRIPT" ]; then
log_error "Beat 启动脚本不存在或不可执行: $BEAT_SCRIPT"
return 1
fi
log_info "启动 Beat 调度服务..."
: > "$BEAT_LOG"
(
cd "$PROJECT_DIR"
exec "$BEAT_SCRIPT"
) >> "$BEAT_LOG" 2>&1 &
pid=$!
echo "$pid" > "$BEAT_PID_FILE"
sleep 2
if pid_alive "$pid"; then
log_success "Beat 启动成功 (PID: $pid)"
return 0
fi
log_error "Beat 启动失败,查看日志: $BEAT_LOG"
tail -20 "$BEAT_LOG" 2>/dev/null || true
rm -f "$BEAT_PID_FILE"
return 1
}
stop_service() {
local name=$1
local pid_file=$2
local port=${3:-}
local pid
pid=$(service_pid "$pid_file")
if ! pid_alive "$pid"; then
if [ -n "$port" ]; then
local stray_pid
stray_pid=$(port_pid "$port")
if [ -n "$stray_pid" ]; then
log_warn "$name PID 文件已失效,正在清理端口 $port 上的残留进程 (PID: $stray_pid)..."
kill_process_tree "$stray_pid"
sleep 1
if pid_alive "$stray_pid"; then
kill -9 "$stray_pid" 2>/dev/null || true
fi
rm -f "$pid_file"
log_success "$name 残留进程已停止"
return 0
fi
fi
rm -f "$pid_file"
log_warn "$name 未运行"
return 0
fi
log_info "停止 $name (PID: $pid)..."
kill "$pid" 2>/dev/null || true
kill_process_tree "$pid"
for _ in $(seq 1 10); do
if ! pid_alive "$pid"; then
local current_port_pid=""
if [ -n "$port" ]; then
current_port_pid=$(port_pid "$port")
fi
if ! pid_alive "$pid" && [ -z "$current_port_pid" ]; then
break
fi
sleep 0.5
done
if pid_alive "$pid"; then
local stubborn_pid=""
if [ -n "$port" ]; then
stubborn_pid=$(port_pid "$port")
fi
if pid_alive "$pid" || [ -n "$stubborn_pid" ]; then
log_warn "$name 未响应,强制终止..."
kill -9 "$pid" 2>/dev/null || true
[ -n "$stubborn_pid" ] && kill -9 "$stubborn_pid" 2>/dev/null || true
fi
rm -f "$pid_file"
log_success "$name 已停止"
@@ -272,12 +355,14 @@ do_start() {
start_backend || return 1
start_frontend || return 1
start_worker || return 1
start_beat || return 1
echo ""
echo -e "${GREEN}============================================${NC}"
echo -e "${GREEN} 前端: http://localhost:$FRONTEND_PUBLIC_PORT (开发服务: $FRONTEND_DEV_PORT)${NC}"
echo -e "${GREEN} 后端: http://localhost:$BACKEND_PORT${NC}"
echo -e "${GREEN} Worker: $WORKER_SCRIPT${NC}"
echo -e "${GREEN} Beat: $BEAT_SCRIPT${NC}"
echo -e "${GREEN} 日志目录: $LOG_DIR${NC}"
echo -e "${GREEN}============================================${NC}"
echo ""
@@ -289,9 +374,10 @@ do_stop() {
echo -e "${YELLOW} 停止 LeAudit 前后端${NC}"
echo -e "${YELLOW}============================================${NC}"
echo ""
stop_service "Beat" "$BEAT_PID_FILE"
stop_service "Worker" "$WORKER_PID_FILE"
stop_service "前端" "$FRONTEND_PID_FILE"
stop_service "后端" "$BACKEND_PID_FILE"
stop_service "前端" "$FRONTEND_PID_FILE" "$FRONTEND_DEV_PORT"
stop_service "后端" "$BACKEND_PID_FILE" "$BACKEND_PORT"
echo ""
}
@@ -305,6 +391,7 @@ do_status() {
cleanup_pid_file "$BACKEND_PID_FILE"
cleanup_pid_file "$FRONTEND_PID_FILE"
cleanup_pid_file "$WORKER_PID_FILE"
cleanup_pid_file "$BEAT_PID_FILE"
echo ""
echo -e "${CYAN}============================================${NC}"
@@ -334,10 +421,18 @@ do_status() {
echo -e " Worker: ${RED}○ 已停止${NC}"
fi
pid=$(service_pid "$BEAT_PID_FILE")
if pid_alive "$pid"; then
echo -e " Beat: ${GREEN}● 运行中${NC} PID=$pid"
else
echo -e " Beat: ${RED}○ 已停止${NC}"
fi
echo ""
echo " 后端日志: $BACKEND_LOG"
echo " 前端日志: $FRONTEND_LOG"
echo " Worker日志: $WORKER_LOG"
echo " Beat日志: $BEAT_LOG"
echo ""
}
@@ -367,10 +462,18 @@ do_logs() {
echo -e "${CYAN}--- Ctrl+C 退出 ---${NC}"
tail -f "$WORKER_LOG"
;;
beat)
[ -f "$BEAT_LOG" ] || touch "$BEAT_LOG"
echo -e "${CYAN}--- Beat 日志 (最近 $lines 行) ---${NC}"
tail -n "$lines" "$BEAT_LOG"
echo -e "${CYAN}--- Ctrl+C 退出 ---${NC}"
tail -f "$BEAT_LOG"
;;
all)
[ -f "$BACKEND_LOG" ] || touch "$BACKEND_LOG"
[ -f "$FRONTEND_LOG" ] || touch "$FRONTEND_LOG"
[ -f "$WORKER_LOG" ] || touch "$WORKER_LOG"
[ -f "$BEAT_LOG" ] || touch "$BEAT_LOG"
echo -e "${CYAN}--- 后端日志 (最近 $lines 行) ---${NC}"
tail -n "$lines" "$BACKEND_LOG"
echo ""
@@ -380,16 +483,20 @@ do_logs() {
echo -e "${CYAN}--- Worker 日志 (最近 $lines 行) ---${NC}"
tail -n "$lines" "$WORKER_LOG"
echo ""
echo -e "${CYAN}--- Beat 日志 (最近 $lines 行) ---${NC}"
tail -n "$lines" "$BEAT_LOG"
echo ""
echo -e "${CYAN}--- Ctrl+C 退出 ---${NC}"
tail -n 0 -f "$BACKEND_LOG" "$FRONTEND_LOG" "$WORKER_LOG" 2>/dev/null | awk '
tail -n 0 -f "$BACKEND_LOG" "$FRONTEND_LOG" "$WORKER_LOG" "$BEAT_LOG" 2>/dev/null | awk '
/^==> .*backend\.log <==$/ { current="[backend]"; next }
/^==> .*frontend\.log <==$/ { current="[frontend]"; next }
/^==> .*worker\.log <==$/ { current="[worker]"; next }
/^==> .*beat\.log <==$/ { current="[beat]"; next }
{ print current " " $0; fflush() }
'
;;
*)
echo "用法: ./leaudit.sh logs [backend|frontend|worker|all] [行数]"
echo "用法: ./leaudit.sh logs [backend|frontend|worker|beat|all] [行数]"
exit 1
;;
esac
@@ -441,6 +548,16 @@ do_doctor() {
echo -e " Worker 进程: ${RED}○ 未运行${NC}"
fi
local beat_pid
beat_pid=$(service_pid "$BEAT_PID_FILE")
if pid_alive "$beat_pid"; then
cmd="$(pid_command "$beat_pid")"
echo -e " Beat 进程: ${GREEN}● 运行中${NC} PID=$beat_pid"
[ -n "$cmd" ] && echo " 命令: $cmd"
else
echo -e " Beat 进程: ${RED}○ 未运行${NC}"
fi
echo ""
}
@@ -454,6 +571,7 @@ do_open() {
echo " 前端开发: http://127.0.0.1:$FRONTEND_DEV_PORT"
echo " 后端访问: http://localhost:$BACKEND_PORT"
echo " Worker脚本: $WORKER_SCRIPT"
echo " Beat脚本: $BEAT_SCRIPT"
echo ""
echo -e "${CYAN}--- 后端最近 5 行 ---${NC}"
tail -n 5 "$BACKEND_LOG" 2>/dev/null || echo "(无后端日志)"
@@ -464,6 +582,9 @@ do_open() {
echo -e "${CYAN}--- Worker最近 5 行 ---${NC}"
tail -n 5 "$WORKER_LOG" 2>/dev/null || echo "(无Worker日志)"
echo ""
echo -e "${CYAN}--- Beat最近 5 行 ---${NC}"
tail -n 5 "$BEAT_LOG" 2>/dev/null || echo "(无Beat日志)"
echo ""
}
case "${1:-help}" in
@@ -492,14 +613,15 @@ case "${1:-help}" in
echo "用法: ./leaudit.sh <命令>"
echo ""
echo "命令说明:"
echo " start 启动前后端"
echo " stop 停止前后端"
echo " restart 重启前后端"
echo " status 查看前后端运行状态"
echo " logs 查看前后端日志并持续跟踪"
echo " start 启动前后端、Worker、Beat"
echo " stop 停止前后端、Worker、Beat"
echo " restart 重启前后端、Worker、Beat"
echo " status 查看前后端、Worker、Beat 运行状态"
echo " logs 查看前后端、Worker、Beat 日志并持续跟踪"
echo " logs backend 只看后端日志"
echo " logs frontend 50 看前端最近 50 行日志并持续跟踪"
echo " logs worker 50 看 Worker 最近 50 行日志并持续跟踪"
echo " logs beat 50 看 Beat 最近 50 行日志并持续跟踪"
echo " doctor 检查 5173 / 5193 / 8096 端口占用情况"
echo " open 打印访问地址和最近日志摘要"
echo ""