mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-12-13 01:18:49 +00:00
feat: enhance development process management and service shutdown
- Introduced a new `stop` target in the Makefile for graceful shutdown of development services, improving user experience during service management. - Updated the `stopProcess` method in the ProcessManager to check if a process is running before attempting to stop it, enhancing reliability. - Improved the shutdown logic to wait for a graceful shutdown before forcefully killing processes, providing clearer logging on the shutdown status. - Enhanced the `dev-kill-all.sh` script to specifically target debros-related processes and improve the cleanup of PID files, ensuring a more thorough shutdown process.
This commit is contained in:
parent
2f1ccfa473
commit
33ebf222ff
15
CHANGELOG.md
15
CHANGELOG.md
@ -13,6 +13,21 @@ The format is based on [Keep a Changelog][keepachangelog] and adheres to [Semant
|
|||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
## [0.69.16] - 2025-11-16
|
||||||
|
|
||||||
|
### Added
|
||||||
|
\n
|
||||||
|
### Changed
|
||||||
|
- Improved the `make stop` command to ensure a more robust and graceful shutdown of development services.
|
||||||
|
- Enhanced the `make kill` command and underlying scripts for more reliable force termination of stray development processes.
|
||||||
|
- Increased the graceful shutdown timeout for development processes from 500ms to 2 seconds before resorting to force kill.
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
\n
|
||||||
## [0.69.15] - 2025-11-16
|
## [0.69.15] - 2025-11-16
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
19
Makefile
19
Makefile
@ -19,7 +19,7 @@ test-e2e:
|
|||||||
|
|
||||||
.PHONY: build clean test run-node run-node2 run-node3 run-example deps tidy fmt vet lint clear-ports install-hooks kill
|
.PHONY: build clean test run-node run-node2 run-node3 run-example deps tidy fmt vet lint clear-ports install-hooks kill
|
||||||
|
|
||||||
VERSION := 0.69.15
|
VERSION := 0.69.16
|
||||||
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||||||
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||||
LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date=$(DATE)'
|
LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date=$(DATE)'
|
||||||
@ -85,13 +85,19 @@ run-gateway:
|
|||||||
dev: build
|
dev: build
|
||||||
@./bin/dbn dev up
|
@./bin/dbn dev up
|
||||||
|
|
||||||
# Kill all processes (graceful shutdown + force kill stray processes)
|
# Graceful shutdown of all dev services
|
||||||
|
stop:
|
||||||
|
@if [ -f ./bin/dbn ]; then \
|
||||||
|
./bin/dbn dev down; \
|
||||||
|
else \
|
||||||
|
echo "⚠️ dbn binary not found, using force kill instead..."; \
|
||||||
|
bash scripts/dev-kill-all.sh; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Force kill all processes (immediate termination)
|
||||||
kill:
|
kill:
|
||||||
@bash scripts/dev-kill-all.sh
|
@bash scripts/dev-kill-all.sh
|
||||||
|
|
||||||
stop:
|
|
||||||
@./bin/dbn dev down
|
|
||||||
|
|
||||||
# Help
|
# Help
|
||||||
help:
|
help:
|
||||||
@echo "Available targets:"
|
@echo "Available targets:"
|
||||||
@ -107,7 +113,8 @@ help:
|
|||||||
@echo " - Validates cluster health (IPFS peers, RQLite, LibP2P)"
|
@echo " - Validates cluster health (IPFS peers, RQLite, LibP2P)"
|
||||||
@echo " - Stops all services if health checks fail"
|
@echo " - Stops all services if health checks fail"
|
||||||
@echo " - Includes comprehensive logging"
|
@echo " - Includes comprehensive logging"
|
||||||
@echo " make kill - Stop all development services"
|
@echo " make stop - Gracefully stop all development services"
|
||||||
|
@echo " make kill - Force kill all development services (use if stop fails)"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Development Management (via dbn):"
|
@echo "Development Management (via dbn):"
|
||||||
@echo " ./bin/dbn dev status - Show status of all dev services"
|
@echo " ./bin/dbn dev status - Show status of all dev services"
|
||||||
|
|||||||
@ -1027,34 +1027,56 @@ func (pm *ProcessManager) stopProcess(name string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if process exists before trying to kill
|
||||||
|
if !checkProcessRunning(pid) {
|
||||||
|
os.Remove(pidPath)
|
||||||
|
fmt.Fprintf(pm.logWriter, "✓ %s (not running)\n", name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
proc, err := os.FindProcess(pid)
|
proc, err := os.FindProcess(pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
os.Remove(pidPath)
|
os.Remove(pidPath)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try graceful shutdown first
|
// Try graceful shutdown first (SIGTERM)
|
||||||
proc.Signal(os.Interrupt)
|
proc.Signal(os.Interrupt)
|
||||||
|
|
||||||
// Wait a bit for graceful shutdown
|
// Wait up to 2 seconds for graceful shutdown
|
||||||
time.Sleep(500 * time.Millisecond)
|
gracefulShutdown := false
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
if !checkProcessRunning(pid) {
|
||||||
|
gracefulShutdown = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if process is still running
|
// Force kill if still running after graceful attempt
|
||||||
if checkProcessRunning(pid) {
|
if !gracefulShutdown && checkProcessRunning(pid) {
|
||||||
// Force kill if still running
|
|
||||||
proc.Signal(os.Kill)
|
proc.Signal(os.Kill)
|
||||||
time.Sleep(200 * time.Millisecond)
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
|
||||||
// Also kill any child processes (platform-specific)
|
// Kill any child processes (platform-specific)
|
||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" {
|
||||||
// Use pkill to kill children on Unix-like systems
|
|
||||||
exec.Command("pkill", "-9", "-P", fmt.Sprintf("%d", pid)).Run()
|
exec.Command("pkill", "-9", "-P", fmt.Sprintf("%d", pid)).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final force kill attempt if somehow still alive
|
||||||
|
if checkProcessRunning(pid) {
|
||||||
|
exec.Command("kill", "-9", fmt.Sprintf("%d", pid)).Run()
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Remove(pidPath)
|
os.Remove(pidPath)
|
||||||
|
|
||||||
fmt.Fprintf(pm.logWriter, "✓ %s stopped\n", name)
|
if gracefulShutdown {
|
||||||
|
fmt.Fprintf(pm.logWriter, "✓ %s stopped gracefully\n", name)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(pm.logWriter, "✓ %s stopped (forced)\n", name)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "Force killing all processes on dev ports..."
|
echo "Force killing all debros development processes..."
|
||||||
|
|
||||||
# Define all dev ports (5 nodes topology: bootstrap, bootstrap2, node2, node3, node4)
|
# Define all dev ports (5 nodes topology: bootstrap, bootstrap2, node2, node3, node4)
|
||||||
PORTS=(
|
PORTS=(
|
||||||
@ -32,16 +32,13 @@ PORTS=(
|
|||||||
killed_count=0
|
killed_count=0
|
||||||
killed_pids=()
|
killed_pids=()
|
||||||
|
|
||||||
# Kill all processes using these ports (LISTEN, ESTABLISHED, or any state)
|
# Method 1: Kill all processes using these ports
|
||||||
for port in "${PORTS[@]}"; do
|
for port in "${PORTS[@]}"; do
|
||||||
# Get all PIDs using this port in ANY TCP state
|
|
||||||
pids=$(lsof -nP -iTCP:"$port" -t 2>/dev/null || true)
|
pids=$(lsof -nP -iTCP:"$port" -t 2>/dev/null || true)
|
||||||
if [[ -n "$pids" ]]; then
|
if [[ -n "$pids" ]]; then
|
||||||
echo "Killing processes on port $port: $pids"
|
echo " Killing processes on port $port: $pids"
|
||||||
for pid in $pids; do
|
for pid in $pids; do
|
||||||
# Kill the process and all its children
|
|
||||||
kill -9 "$pid" 2>/dev/null || true
|
kill -9 "$pid" 2>/dev/null || true
|
||||||
# Also kill any children of this process
|
|
||||||
pkill -9 -P "$pid" 2>/dev/null || true
|
pkill -9 -P "$pid" 2>/dev/null || true
|
||||||
killed_pids+=("$pid")
|
killed_pids+=("$pid")
|
||||||
done
|
done
|
||||||
@ -49,18 +46,26 @@ for port in "${PORTS[@]}"; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Also kill processes by command name patterns (in case they're orphaned)
|
# Method 2: Kill processes by specific patterns (ONLY debros-related)
|
||||||
# This catches processes that might be using debros ports but not showing up in lsof
|
# Be very specific to avoid killing unrelated processes
|
||||||
COMMANDS=("node" "ipfs" "ipfs-cluster-service" "rqlited" "olric-server" "gateway")
|
SPECIFIC_PATTERNS=(
|
||||||
for cmd in "${COMMANDS[@]}"; do
|
"ipfs daemon"
|
||||||
# Find all processes with this command name
|
"ipfs-cluster-service daemon"
|
||||||
all_pids=$(pgrep -f "^.*$cmd.*" 2>/dev/null || true)
|
"olric-server"
|
||||||
|
"bin/node"
|
||||||
|
"bin/gateway"
|
||||||
|
"anyone-client"
|
||||||
|
)
|
||||||
|
|
||||||
|
for pattern in "${SPECIFIC_PATTERNS[@]}"; do
|
||||||
|
# Use exact pattern matching to avoid false positives
|
||||||
|
all_pids=$(pgrep -f "$pattern" 2>/dev/null || true)
|
||||||
if [[ -n "$all_pids" ]]; then
|
if [[ -n "$all_pids" ]]; then
|
||||||
for pid in $all_pids; do
|
for pid in $all_pids; do
|
||||||
# Check if this process is using any of our dev ports
|
# Double-check the command line to avoid killing wrong processes
|
||||||
port_match=$(lsof -nP -p "$pid" -iTCP 2>/dev/null | grep -E ":(400[1-4]|401[1-1]|410[1-4]|411[1-1]|450[1-4]|451[1-1]|500[1-4]|501[1-1]|600[1-1]|700[1-4]|701[1-1]|750[1-4]|751[1-1]|332[02]|9050|909[4-9]|910[4-9]|911[4-9]|912[4-9]|913[4-9]|909[6-9]|910[6-9]|911[6-9]|912[6-9]|913[6-9])" || true)
|
cmdline=$(ps -p "$pid" -o command= 2>/dev/null || true)
|
||||||
if [[ -n "$port_match" ]]; then
|
if [[ "$cmdline" == *"$pattern"* ]]; then
|
||||||
echo "Killing orphaned $cmd process (PID: $pid) using dev ports"
|
echo " Killing $pattern process (PID: $pid)"
|
||||||
kill -9 "$pid" 2>/dev/null || true
|
kill -9 "$pid" 2>/dev/null || true
|
||||||
pkill -9 -P "$pid" 2>/dev/null || true
|
pkill -9 -P "$pid" 2>/dev/null || true
|
||||||
killed_pids+=("$pid")
|
killed_pids+=("$pid")
|
||||||
@ -69,26 +74,40 @@ for cmd in "${COMMANDS[@]}"; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Clean up PID files
|
# Method 3: Kill processes using PID files
|
||||||
PIDS_DIR="$HOME/.debros/.pids"
|
PIDS_DIR="$HOME/.debros/.pids"
|
||||||
if [[ -d "$PIDS_DIR" ]]; then
|
if [[ -d "$PIDS_DIR" ]]; then
|
||||||
rm -f "$PIDS_DIR"/*.pid || true
|
for pidfile in "$PIDS_DIR"/*.pid; do
|
||||||
|
if [[ -f "$pidfile" ]]; then
|
||||||
|
pid=$(cat "$pidfile" 2>/dev/null || true)
|
||||||
|
if [[ -n "$pid" ]] && ps -p "$pid" > /dev/null 2>&1; then
|
||||||
|
name=$(basename "$pidfile" .pid)
|
||||||
|
echo " Killing $name (PID: $pid from pidfile)"
|
||||||
|
kill -9 "$pid" 2>/dev/null || true
|
||||||
|
pkill -9 -P "$pid" 2>/dev/null || true
|
||||||
|
killed_pids+=("$pid")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# Clean up all PID files
|
||||||
|
rm -f "$PIDS_DIR"/*.pid 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Remove duplicates and report
|
# Remove duplicates and report
|
||||||
if [[ ${#killed_pids[@]} -gt 0 ]]; then
|
if [[ ${#killed_pids[@]} -gt 0 ]]; then
|
||||||
unique_pids=($(printf '%s\n' "${killed_pids[@]}" | sort -u))
|
unique_pids=($(printf '%s\n' "${killed_pids[@]}" | sort -u))
|
||||||
echo "✓ Killed ${#unique_pids[@]} unique process(es) on $killed_count port(s)"
|
echo "✓ Killed ${#unique_pids[@]} unique process(es)"
|
||||||
else
|
else
|
||||||
echo "✓ No processes found on dev ports"
|
echo "✓ No debros processes found running"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Final verification: check if any ports are still in use
|
# Final verification: check if any ports are still in use
|
||||||
still_in_use=0
|
still_in_use=0
|
||||||
|
busy_ports=()
|
||||||
for port in "${PORTS[@]}"; do
|
for port in "${PORTS[@]}"; do
|
||||||
pids=$(lsof -nP -iTCP:"$port" -t 2>/dev/null || true)
|
pids=$(lsof -nP -iTCP:"$port" -t 2>/dev/null || true)
|
||||||
if [[ -n "$pids" ]]; then
|
if [[ -n "$pids" ]]; then
|
||||||
echo "⚠️ Warning: Port $port still in use by: $pids"
|
busy_ports+=("$port")
|
||||||
still_in_use=$((still_in_use + 1))
|
still_in_use=$((still_in_use + 1))
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@ -96,6 +115,7 @@ done
|
|||||||
if [[ $still_in_use -eq 0 ]]; then
|
if [[ $still_in_use -eq 0 ]]; then
|
||||||
echo "✓ All dev ports are now free"
|
echo "✓ All dev ports are now free"
|
||||||
else
|
else
|
||||||
echo "⚠️ $still_in_use port(s) still in use - you may need to manually kill processes"
|
echo "⚠️ Warning: $still_in_use port(s) still in use: ${busy_ports[*]}"
|
||||||
|
echo " Run 'lsof -nP -iTCP:<port>' to identify the processes"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user