Aniworld/stop_server.sh
Lukas d70d70e193 feat: implement graceful shutdown with SIGINT/SIGTERM support
- Add WebSocket shutdown() with client notification and graceful close
- Enhance download service stop() with pending state persistence
- Expand FastAPI lifespan shutdown with proper cleanup sequence
- Add SQLite WAL checkpoint before database close
- Update stop_server.sh to use SIGTERM with timeout fallback
- Configure uvicorn timeout_graceful_shutdown=30s
- Update ARCHITECTURE.md with shutdown documentation
2025-12-25 18:59:07 +01:00

95 lines
2.7 KiB
Bash

#!/bin/bash
# Stop Aniworld FastAPI Server (Graceful Shutdown)
#
# This script performs a graceful shutdown by sending SIGTERM first,
# allowing the application to clean up resources properly before
# falling back to SIGKILL if needed.
GRACEFUL_TIMEOUT=30 # seconds to wait for graceful shutdown
echo "Stopping Aniworld server (graceful shutdown)..."
# Function to wait for a process to terminate
wait_for_process() {
local pid=$1
local timeout=$2
local count=0
while [ $count -lt $timeout ]; do
if ! kill -0 "$pid" 2>/dev/null; then
return 0 # Process terminated
fi
sleep 1
count=$((count + 1))
echo -ne "\r Waiting for graceful shutdown... ${count}/${timeout}s"
done
echo ""
return 1 # Timeout
}
# Method 1: Gracefully stop uvicorn processes
UVICORN_PIDS=$(pgrep -f "uvicorn.*fastapi_app:app")
if [ -n "$UVICORN_PIDS" ]; then
echo "Sending SIGTERM to uvicorn processes..."
for pid in $UVICORN_PIDS; do
kill -TERM "$pid" 2>/dev/null
done
# Wait for graceful shutdown
all_terminated=true
for pid in $UVICORN_PIDS; do
if ! wait_for_process "$pid" "$GRACEFUL_TIMEOUT"; then
all_terminated=false
echo " Process $pid did not terminate gracefully, forcing..."
kill -9 "$pid" 2>/dev/null
fi
done
if $all_terminated; then
echo "✓ Uvicorn processes stopped gracefully"
else
echo "✓ Uvicorn processes stopped (forced)"
fi
else
echo "✓ No uvicorn processes running"
fi
# Method 2: Gracefully stop any process using port 8000
PORT_PID=$(lsof -ti:8000)
if [ -n "$PORT_PID" ]; then
echo "Found process on port 8000 (PID: $PORT_PID)"
# Send SIGTERM first
kill -TERM "$PORT_PID" 2>/dev/null
if wait_for_process "$PORT_PID" "$GRACEFUL_TIMEOUT"; then
echo "✓ Process on port 8000 stopped gracefully"
else
echo " Graceful shutdown timed out, forcing..."
kill -9 "$PORT_PID" 2>/dev/null
echo "✓ Process on port 8000 stopped (forced)"
fi
else
echo "✓ Port 8000 is already free"
fi
# Method 3: Gracefully stop run_server.py processes
SERVER_PIDS=$(pgrep -f "run_server.py")
if [ -n "$SERVER_PIDS" ]; then
echo "Sending SIGTERM to run_server.py processes..."
for pid in $SERVER_PIDS; do
kill -TERM "$pid" 2>/dev/null
done
for pid in $SERVER_PIDS; do
if ! wait_for_process "$pid" 10; then
kill -9 "$pid" 2>/dev/null
fi
done
echo "✓ Stopped run_server.py processes"
fi
echo ""
echo "Server stopped successfully!"
echo "You can restart it with: ./start_server.sh"