#!/bin/bash # Wrapper script that auto-restarts uvicorn on crash # Usage: ./run-with-restart.sh [port] [log_file] # Get script directory and activate venv SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/venv/bin/activate" PORT=${1:-8000} LOG_FILE=${2:-/tmp/unified_backend.log} MAX_RESTARTS=10 RESTART_COUNT=0 RESTART_DELAY=3 UVICORN_PID="" # On SIGTERM or SIGINT: kill uvicorn child and exit cleanly (no restart) cleanup_and_exit() { echo "[Backend Runner] Received termination signal, stopping..." | tee -a "$LOG_FILE" if [ -n "$UVICORN_PID" ] && kill -0 "$UVICORN_PID" 2>/dev/null; then kill "$UVICORN_PID" 2>/dev/null wait "$UVICORN_PID" 2>/dev/null fi exit 0 } trap cleanup_and_exit SIGTERM SIGINT echo "[Backend Runner] Starting uvicorn with auto-restart (max $MAX_RESTARTS restarts)" | tee -a "$LOG_FILE" echo "[Backend Runner] Port: $PORT, Log: $LOG_FILE" | tee -a "$LOG_FILE" while [ $RESTART_COUNT -lt $MAX_RESTARTS ]; do START_TIME=$(date +%s) echo "" | tee -a "$LOG_FILE" echo "[Backend Runner] $(date '+%Y-%m-%d %H:%M:%S') - Starting uvicorn (attempt $((RESTART_COUNT + 1))/$MAX_RESTARTS)..." | tee -a "$LOG_FILE" # Run uvicorn in background so we can track its PID and trap signals properly uvicorn main:app --host 0.0.0.0 --port "$PORT" >> "$LOG_FILE" 2>&1 & UVICORN_PID=$! # Wait for uvicorn to exit wait "$UVICORN_PID" EXIT_CODE=$? UVICORN_PID="" END_TIME=$(date +%s) RUNTIME=$((END_TIME - START_TIME)) echo "[Backend Runner] $(date '+%Y-%m-%d %H:%M:%S') - uvicorn exited with code $EXIT_CODE after ${RUNTIME}s" | tee -a "$LOG_FILE" # Exit if trap already fired (cleanup_and_exit sets UVICORN_PID="") # or if uvicorn exited due to a signal (130=SIGINT, 143=SIGTERM, 137=SIGKILL) if [ $EXIT_CODE -eq 130 ] || [ $EXIT_CODE -eq 143 ] || [ $EXIT_CODE -eq 137 ]; then echo "[Backend Runner] Received termination signal (code $EXIT_CODE), exiting..." | tee -a "$LOG_FILE" exit 0 fi # If it ran for more than 60 seconds, reset restart counter (was stable) if [ $RUNTIME -gt 60 ]; then RESTART_COUNT=0 echo "[Backend Runner] Process was stable (>${RUNTIME}s), resetting restart counter" | tee -a "$LOG_FILE" else RESTART_COUNT=$((RESTART_COUNT + 1)) echo "[Backend Runner] Quick crash detected, restart count: $RESTART_COUNT/$MAX_RESTARTS" | tee -a "$LOG_FILE" fi # Wait before restart if [ $RESTART_COUNT -lt $MAX_RESTARTS ]; then echo "[Backend Runner] Restarting in ${RESTART_DELAY}s..." | tee -a "$LOG_FILE" sleep $RESTART_DELAY fi done echo "[Backend Runner] Max restarts ($MAX_RESTARTS) reached. Giving up." | tee -a "$LOG_FILE" exit 1