- 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
95 lines
2.7 KiB
Bash
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"
|