diff --git a/scripts/local-debug/start.sh b/scripts/local-debug/start.sh index d39a5a3..d1e2827 100755 --- a/scripts/local-debug/start.sh +++ b/scripts/local-debug/start.sh @@ -60,6 +60,60 @@ wait_for_pid_exit() { return 1 } +descendant_pids() { + local pid="$1" + local child + while IFS= read -r child; do + [[ -n "$child" ]] || continue + printf '%s\n' "$child" + descendant_pids "$child" + done < <(pgrep -P "$pid" 2>/dev/null || true) +} + +stop_pid_tree() { + local name="$1" + local root_pid="$2" + local pids + local pid + local forced=0 + + [[ "$root_pid" =~ ^[0-9]+$ ]] || return 0 + pids="$(descendant_pids "$root_pid"; printf '%s\n' "$root_pid")" + for pid in $pids; do + kill "$pid" 2>/dev/null || true + done + for pid in $pids; do + if ! wait_for_pid_exit "$pid"; then + forced=1 + fi + done + if [[ "$forced" -eq 1 ]]; then + printf '%s process tree rooted at pid %s did not stop after SIGTERM; sending SIGKILL\n' "$name" "$root_pid" + for pid in $pids; do + kill -9 "$pid" 2>/dev/null || true + done + for pid in $pids; do + wait_for_pid_exit "$pid" || true + done + fi +} + +stop_orphaned_run_bootstrap() { + local pid_file="$LOCAL_DEBUG_PID_DIR/run.pid" + local pid + if managed_pid_running "$pid_file"; then + return 0 + fi + while IFS= read -r pid; do + [[ "$pid" =~ ^[0-9]+$ ]] || continue + [[ "$pid" != "$$" ]] || continue + if kill -0 "$pid" 2>/dev/null; then + printf 'stopping stale run bootstrap pid %s before start\n' "$pid" + stop_pid_tree "run bootstrap" "$pid" + fi + done < <(pgrep -f "$RUN_BOOTSTRAP_BIN" 2>/dev/null || true) +} + ensure_port_available() { local name="$1" local port="$2" @@ -228,6 +282,7 @@ start_service platform_web "$ROOT_DIR" env \ wait_for_url platform_web "$(local_debug_web_url)" +stop_orphaned_run_bootstrap local_debug_build_bootstrap_run start_service run "$(dirname "$RUN_BOOTSTRAP_BIN")" env \ GOCACHE="$GOCACHE" \ diff --git a/scripts/local-debug/stop.sh b/scripts/local-debug/stop.sh index ee6f932..3cea887 100755 --- a/scripts/local-debug/stop.sh +++ b/scripts/local-debug/stop.sh @@ -5,6 +5,70 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" # shellcheck source=scripts/local-debug/env.sh source "$ROOT_DIR/scripts/local-debug/env.sh" +wait_for_pid_exit() { + local pid="$1" + for _ in $(seq 1 20); do + if ! kill -0 "$pid" 2>/dev/null; then + return 0 + fi + sleep 0.25 + done + return 1 +} + +descendant_pids() { + local pid="$1" + local child + while IFS= read -r child; do + [[ -n "$child" ]] || continue + printf '%s\n' "$child" + descendant_pids "$child" + done < <(pgrep -P "$pid" 2>/dev/null || true) +} + +stop_pid_tree() { + local name="$1" + local root_pid="$2" + local pids + local pid + local forced=0 + + [[ "$root_pid" =~ ^[0-9]+$ ]] || return 0 + pids="$(descendant_pids "$root_pid"; printf '%s\n' "$root_pid")" + for pid in $pids; do + kill "$pid" 2>/dev/null || true + done + for pid in $pids; do + if ! wait_for_pid_exit "$pid"; then + forced=1 + fi + done + if [[ "$forced" -eq 1 ]]; then + printf '%s process tree rooted at pid %s did not stop after SIGTERM; sending SIGKILL\n' "$name" "$root_pid" + for pid in $pids; do + kill -9 "$pid" 2>/dev/null || true + done + for pid in $pids; do + wait_for_pid_exit "$pid" || true + done + fi +} + +stop_matching_processes() { + local name="$1" + local pattern="$2" + local pid + [[ -n "$pattern" ]] || return 0 + while IFS= read -r pid; do + [[ "$pid" =~ ^[0-9]+$ ]] || continue + [[ "$pid" != "$$" ]] || continue + if kill -0 "$pid" 2>/dev/null; then + printf 'stopping stale %s pid %s\n' "$name" "$pid" + stop_pid_tree "$name" "$pid" + fi + done < <(pgrep -f "$pattern" 2>/dev/null || true) +} + if [[ ! -d "$LOCAL_DEBUG_PID_DIR" ]]; then printf 'no local debug pid directory at %s\n' "$LOCAL_DEBUG_PID_DIR" else @@ -22,7 +86,7 @@ else pid="$(<"$pid_file")" if kill -0 "$pid" 2>/dev/null; then printf 'stopping %s pid %s\n' "$name" "$pid" - kill "$pid" 2>/dev/null || true + stop_pid_tree "$name" "$pid" else printf '%s pid %s is not running\n' "$name" "$pid" fi @@ -30,16 +94,7 @@ else done fi -wait_for_pid_exit() { - local pid="$1" - for _ in $(seq 1 20); do - if ! kill -0 "$pid" 2>/dev/null; then - return 0 - fi - sleep 0.25 - done - return 1 -} +stop_matching_processes "run bootstrap" "$RUN_BOOTSTRAP_BIN" listener_owned_by_local_debug() { local pid="$1"