#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" RUN_DIR="$ROOT_DIR/run" PID_FILE="$RUN_DIR/hy-app-monitor.pid" LOG_FILE="$RUN_DIR/hy-app-monitor.log" ENV_FILE="${APP_ENV_FILE:-$ROOT_DIR/.env}" SYSTEMD_SERVICE_NAME="hy-app-monitor.service" if [ -f "$ENV_FILE" ]; then set -a # shellcheck disable=SC1090 . "$ENV_FILE" set +a fi APP_BIND="${APP_BIND:-0.0.0.0}" APP_PORT="${APP_PORT:-2026}" TARGETS_FILE="${TARGETS_FILE:-$ROOT_DIR/config/targets.json}" if [ -x "$ROOT_DIR/.venv/bin/python" ]; then PYTHON_BIN_DEFAULT="$ROOT_DIR/.venv/bin/python" else PYTHON_BIN_DEFAULT="python3" fi PYTHON_BIN="${PYTHON_BIN:-$PYTHON_BIN_DEFAULT}" mkdir -p "$RUN_DIR" read_pid() { if [ -f "$PID_FILE" ]; then local pid pid="$(cat "$PID_FILE")" if pid_matches_project "$pid"; then echo "$pid" return 0 fi fi discover_project_pid } is_running() { local pid pid="$(read_pid || true)" if [ -z "${pid:-}" ]; then rm -f "$PID_FILE" return 1 fi if ! kill -0 "$pid" >/dev/null 2>&1; then rm -f "$PID_FILE" return 1 fi echo "$pid" >"$PID_FILE" return 0 } has_systemd_unit() { if ! command -v systemctl >/dev/null 2>&1; then return 1 fi systemctl cat "$SYSTEMD_SERVICE_NAME" >/dev/null 2>&1 } stop_legacy_process() { local pid pid="$(read_pid || true)" if [ -n "${pid:-}" ] && kill -0 "$pid" >/dev/null 2>&1; then kill "$pid" >/dev/null 2>&1 || true for _ in $(seq 1 10); do if ! kill -0 "$pid" >/dev/null 2>&1; then break fi sleep 1 done kill -9 "$pid" >/dev/null 2>&1 || true fi rm -f "$PID_FILE" } discover_project_pid() { if ! command -v lsof >/dev/null 2>&1; then return 1 fi local pid while IFS= read -r pid; do if pid_matches_project "$pid"; then echo "$pid" return 0 fi done < <(lsof -tiTCP:"$APP_PORT" -sTCP:LISTEN 2>/dev/null || true) return 1 } pid_matches_project() { local pid="$1" if [ -z "${pid:-}" ] || ! kill -0 "$pid" >/dev/null 2>&1; then return 1 fi local command command="$(ps -p "$pid" -o command= 2>/dev/null || true)" if [[ "$command" != *"$ROOT_DIR/server.py"* ]] && [[ "$command" != *" server.py"* ]]; then return 1 fi if command -v lsof >/dev/null 2>&1; then local cwd cwd="$(lsof -a -p "$pid" -d cwd -Fn 2>/dev/null | sed -n 's/^n//p' | head -n 1)" if [ -n "$cwd" ] && [ "$cwd" != "$ROOT_DIR" ]; then return 1 fi fi return 0 }