diff --git a/backend/dev.sh b/backend/dev.sh index f4d9a15..36a15c6 100755 --- a/backend/dev.sh +++ b/backend/dev.sh @@ -70,6 +70,8 @@ start_service() { "$SCRIPT_DIR/$binary" -port=$port > "/tmp/${name}.log" 2>&1 & fi local pid=$! + # 保存 PID 到文件 + echo $pid > "/tmp/dev_sh_${name}.pid" sleep 2 @@ -101,4 +103,111 @@ build_service() { echo -e "${RED}❌ $name 编译失败${NC}" return 1 fi +} + +# 重建并重启单个服务(构建成功后才杀旧进程) +# 用法: restart_service name dir binary port use_db +restart_service() { + local name=$1 + local dir=$2 + local binary=$3 + local port=$4 + local use_db=$5 + local pid_file="/tmp/dev_sh_${name}.pid" + + # Step 1: 编译(先编译,编译成功才杀旧进程) + if [ ! -d "$SCRIPT_DIR/$dir" ]; then + echo -e "${RED}❌ $dir 目录不存在,跳过${NC}" + return 1 + fi + + cd "$SCRIPT_DIR/$dir" + if ! go build -o "$SCRIPT_DIR/$binary" . 2>&1; then + echo -e "${RED}❌ [$name] 编译失败,旧进程保持运行${NC}" + echo -e "${RED} 查看详细日志: tail -f /tmp/${name}.log${NC}" + return 1 + fi + echo -e "${GREEN}✅ [$name] 编译成功${NC}" + + # Step 2: 编译成功后,杀旧进程(从 PID 文件读取) + if [ -f "$pid_file" ]; then + local old_pid=$(cat "$pid_file") + if [ -n "$old_pid" ] && kill -0 "$old_pid" 2>/dev/null; then + kill "$old_pid" 2>/dev/null || true + echo -e "${YELLOW}🛑 [$name] 旧进程 (PID: $old_pid) 已终止${NC}" + fi + rm -f "$pid_file" + fi + + # Step 3: 启动新进程 + sleep 1 + cd "$SCRIPT_DIR" + if [ "$use_db" = "1" ]; then + "$SCRIPT_DIR/$binary" -port=$port "${DB_ARGS[@]}" > "/tmp/${name}.log" 2>&1 & + else + "$SCRIPT_DIR/$binary" -port=$port > "/tmp/${name}.log" 2>&1 & + fi + local new_pid=$! + echo $new_pid > "$pid_file" + sleep 2 + + if ps -p $new_pid > /dev/null 2>&1; then + echo -e "${GREEN}✅ [$name] 已重启 (PID: $new_pid)${NC}" + else + echo -e "${RED}❌ [$name] 重启失败,查看日志: tail -f /tmp/${name}.log${NC}" + fi +} + +# 启动文件监听器 +# 用法: start_watcher name dir binary port use_db +start_watcher() { + local name=$1 + local dir=$2 + local binary=$3 + local port=$4 + local use_db=$5 + local watch_path="$SCRIPT_DIR/$dir" + local restart_marker="/tmp/dev_sh_${name}_restart" + + if [ ! -d "$watch_path" ]; then + echo -e "${RED}❌ 监听目录不存在: $watch_path${NC}" + return 1 + fi + + # 清理可能遗留的重启标记 + rm -f "$restart_marker" + + ( + if [[ "$(uname)" == "Darwin" ]]; then + fswatch -r "$watch_path" --exclude='\.git' --exclude='_test\.go$' + else + inotifywait -r -m -e modify,create,write "$watch_path" --exclude='\.git' --exclude='_test\.go$' + fi | while read event; do + # 时间戳防抖:每次事件更新标记文件 + date +%s%N > "$restart_marker" + done + ) & + local watcher_pid=$! + echo "$watcher_pid" >> /tmp/dev_sh_watchers.tmp + echo -e "${GREEN}👁️ [$name] 文件监听器已启动 (PID: $watcher_pid)${NC}" + + # 后台防抖循环:每 300ms 检查一次是否需要重启 + ( + while true; do + sleep 0.3 + if [ ! -f "$restart_marker" ]; then + continue + fi + local now=$(date +%s%N) + local last_time=$(cat "$restart_marker" 2>/dev/null || echo 0) + local elapsed=$((now - last_time)) + if (( elapsed >= 300000000 )); then + # 距上次事件已过 300ms,执行重启 + rm -f "$restart_marker" + restart_service "$name" "$dir" "$binary" "$port" "$use_db" + fi + done + ) & + local debounce_pid=$! + echo "$debounce_pid" >> /tmp/dev_sh_watchers.tmp } \ No newline at end of file