fix: tolerate agent stalls and self-heal instead of dropping all ExApp routing - #111
Conversation
9ab37f3 to
141d345
Compare
📝 WalkthroughWalkthroughThe HaRP agent now provides a lightweight 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: a62ecaed-ffc5-48bb-8cc5-9a77b02dd30e
📒 Files selected for processing (5)
README.mdhaproxy.cfg.templatehaproxy_agent.pyhealthcheck.shstart.sh
141d345 to
6ea04f9
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
start.sh (1)
487-523: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winIdentify which process died in the exit message for faster incident triage.
Line 519 logs a generic "a HaRP process exited unexpectedly" without naming which of haproxy/agent/frps/frpc/watchdog actually died. Given this whole PR is about diagnosing/recovering from agent stalls, naming the culprit directly in the log would meaningfully speed up on-call triage, and can be done with a simple
kill -0scan afterwait -n(no need for the Bash 5.1-onlywait -n -p, keeping the existing Bash 4.3+ requirement).🔍 Proposed diagnostic improvement
wait -n rc=$? -echo "ERROR: a HaRP process exited unexpectedly (status ${rc}), stopping the container." +dead="unknown" +for entry in "haproxy:$HAPROXY_PID" "agent:$AGENT_PID" "frps:$FRPS_PID" ${FRPC_PID:+"frpc:$FRPC_PID"} ${WATCHDOG_PID:+"watchdog:$WATCHDOG_PID"}; do + pid="${entry#*:}" + kill -0 "$pid" 2>/dev/null || { dead="${entry%%:*}"; break; } +done +echo "ERROR: HaRP process '${dead}' exited unexpectedly (status ${rc}), stopping the container." [ -n "${WATCHDOG_PID:-}" ] && kill "$WATCHDOG_PID" 2>/dev/null
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: bf120867-d495-4498-b23f-ea7c6729da0f
📒 Files selected for processing (6)
DockerfileREADME.mdhaproxy.cfg.templatehaproxy_agent.pyhealthcheck.shstart.sh
🚧 Files skipped from review as they are similar to previous changes (3)
- haproxy.cfg.template
- healthcheck.sh
- haproxy_agent.py
5e7190b to
8c40a82
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
start.sh (1)
501-523: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDedupe the hardcoded agent heartbeat URL.
http://127.0.0.1:8200/heartbeatis now hardcoded a third time (already literal at lines 468-469 for the readiness probe). If the agent's listen port/path ever changes and only one copy is updated, the watchdog would silently start treating a healthy agent as permanently unresponsive, repeatedly killing/restarting it.♻️ Proposed fix: single source of truth for the URL
+AGENT_HEARTBEAT_URL="http://127.0.0.1:8200/heartbeat" + # Wait deterministically for the agent to be ready (HTTP) and for SPOA (TCP). # Probe /heartbeat, not /info: /info can block on a K8s API reachability check. -log "INFO: Waiting for HaRP Agent HTTP (GET http://127.0.0.1:8200/heartbeat) to be ready..." -wait_for_http "http://127.0.0.1:8200/heartbeat" "$HP_WAIT_AGENT_HTTP" "$HP_WAIT_INTERVAL" +log "INFO: Waiting for HaRP Agent HTTP (GET ${AGENT_HEARTBEAT_URL}) to be ready..." +wait_for_http "$AGENT_HEARTBEAT_URL" "$HP_WAIT_AGENT_HTTP" "$HP_WAIT_INTERVAL"- if curl -fsS --noproxy '*' --max-time 5 http://127.0.0.1:8200/heartbeat >/dev/null 2>&1; then + if curl -fsS --noproxy '*' --max-time 5 "$AGENT_HEARTBEAT_URL" >/dev/null 2>&1; then
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 971b968c-d09f-4f62-aee6-83b481597c02
📒 Files selected for processing (6)
DockerfileREADME.mdhaproxy.cfg.templatehaproxy_agent.pyhealthcheck.shstart.sh
🚧 Files skipped from review as they are similar to previous changes (5)
- README.md
- healthcheck.sh
- haproxy.cfg.template
- Dockerfile
- haproxy_agent.py
…p routing Signed-off-by: Oleksander Piskun <oleksandr2088@icloud.com>
8c40a82 to
55dd8a9
Compare
Fixes #110: the outages are not HAProxy refusing to reconnect, they happen because the whole Python agent (SPOA auth, the control API and the
frpsLogin hook share one event loop) stops responding under load, the SPOP check tolerates only about 6 seconds of that before all/exappsrouting goes down, and nothing detects or restarts a hung agent.🤖 AI (if applicable)