sethmcknight commited on
Commit
307e1fd
·
1 Parent(s): a0280a8

refactor: enhance run script for better signal handling and diagnostics

Browse files
Files changed (1) hide show
  1. run.sh +40 -10
run.sh CHANGED
@@ -1,5 +1,5 @@
1
  #!/usr/bin/env bash
2
- set -e
3
 
4
  # Default to 1 worker to prevent OOM on low-memory hosts
5
  WORKERS_VALUE="${WORKERS:-1}"
@@ -13,21 +13,51 @@ python scripts/init_pgvector.py
13
  echo "Starting gunicorn on port ${PORT_VALUE} with ${WORKERS_VALUE} workers and timeout ${TIMEOUT_VALUE}s"
14
  export PYTHONPATH="/app${PYTHONPATH:+:$PYTHONPATH}"
15
 
16
- # Start gunicorn in the background and pre-warm the application
17
- gunicorn --bind 0.0.0.0:${PORT_VALUE} --workers "${WORKERS_VALUE}" --timeout "${TIMEOUT_VALUE}" --config gunicorn.conf.py app:app &
 
 
 
 
 
 
 
 
 
 
18
  GUNICORN_PID=$!
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  echo "Waiting for server to start to pre-warm..."
21
- sleep 15 # Wait for gunicorn to start
22
 
 
23
  echo "Pre-warming application..."
24
- curl -X POST http://localhost:${PORT_VALUE}/chat \
25
  -H "Content-Type: application/json" \
26
- -d '{"message": "pre-warm"}' \
27
- --max-time 180 \
28
- --fail || echo "Pre-warm request failed but continuing..."
29
 
30
  echo "Server is running."
31
 
32
- # Wait for the gunicorn process to exit
33
- wait $GUNICORN_PID
 
 
 
 
1
  #!/usr/bin/env bash
2
+ set -euo pipefail
3
 
4
  # Default to 1 worker to prevent OOM on low-memory hosts
5
  WORKERS_VALUE="${WORKERS:-1}"
 
13
  echo "Starting gunicorn on port ${PORT_VALUE} with ${WORKERS_VALUE} workers and timeout ${TIMEOUT_VALUE}s"
14
  export PYTHONPATH="/app${PYTHONPATH:+:$PYTHONPATH}"
15
 
16
+ # Start gunicorn in background so we can trap signals and collect diagnostics
17
+ gunicorn \
18
+ --bind 0.0.0.0:${PORT_VALUE} \
19
+ --workers "${WORKERS_VALUE}" \
20
+ --timeout "${TIMEOUT_VALUE}" \
21
+ --log-level debug \
22
+ --access-logfile - \
23
+ --error-logfile - \
24
+ --capture-output \
25
+ --config gunicorn.conf.py \
26
+ app:app &
27
+
28
  GUNICORN_PID=$!
29
 
30
+ # Trap TERM and INT, log diagnostics, forward the signal to gunicorn, and wait
31
+ handle_term() {
32
+ echo "===== SIGTERM received at $(date -u +'%Y-%m-%dT%H:%M:%SZ') ====="
33
+ echo "--- Top processes by RSS ---"
34
+ ps aux --sort=-rss | head -n 20 || true
35
+ echo "--- /proc/meminfo (if available) ---"
36
+ cat /proc/meminfo || true
37
+ echo "Forwarding SIGTERM to gunicorn (pid ${GUNICORN_PID})"
38
+ kill -TERM "${GUNICORN_PID}" 2>/dev/null || true
39
+ # Wait for gunicorn to exit
40
+ wait "${GUNICORN_PID}" || true
41
+ echo "Gunicorn exited; wrapper exiting"
42
+ exit 0
43
+ }
44
+ trap 'handle_term' SIGTERM SIGINT
45
+
46
+ # Give gunicorn a moment to start before pre-warm
47
  echo "Waiting for server to start to pre-warm..."
48
+ sleep 5
49
 
50
+ # Pre-warm application (best-effort; don't fail startup if warm request fails)
51
  echo "Pre-warming application..."
52
+ curl -sS -X POST http://localhost:${PORT_VALUE}/chat \
53
  -H "Content-Type: application/json" \
54
+ -d '{"message":"pre-warm"}' \
55
+ --max-time 180 --fail >/dev/null 2>&1 || echo "Pre-warm request failed but continuing..."
 
56
 
57
  echo "Server is running."
58
 
59
+ # Wait for gunicorn to exit and forward its exit code
60
+ wait "${GUNICORN_PID}"
61
+ EXIT_CODE=$?
62
+ echo "Gunicorn stopped with exit code ${EXIT_CODE}"
63
+ exit "${EXIT_CODE}"