Problem
When an agent pod is killed mid-conversation (due to rolling updates, OOM, or node eviction), the in-flight run is lost. The user sees a frozen chat with no way to resume. There is no mechanism to track active runs, persist their state, or recover them on a replacement pod.
Expected Behavior
When a pod is killed mid-run:
- The shutdown hook should mark the active run as interrupted in Redis + Postgres with the latest checkpoint_id
- A replacement pod should claim the interrupted run on startup and resume from the last completed graph node
- The UI should detect the resumed run completing and render the response seamlessly
Proposed Solution
Add a lifecycle state persistence engine (lifecycle.py) that:
- Registers in-flight runs in Redis with TTL-based leases
- Updates checkpoint progress on each graph node completion
- Persists state on shutdown (SIGTERM) — marks all local in-flight runs as interrupted
- Resumes on startup — claims interrupted runs using
FOR UPDATE SKIP LOCKED to prevent duplicate processing across replicas, then re-enqueues through the Aegra worker executor
- Encrypts tokens via Fernet (derived from SSO_CLIENT_SECRET) for sensitive data stored in Redis
Files to modify
startup.py — call resume_interrupted_runs on pod startup
shutdown.py — call persist_inflight_runs during graceful shutdown
graph.py — integrate lifecycle tracking (register, update, deregister)
Acceptance Criteria
References
- Internal tracker: RHITAIF-206
Problem
When an agent pod is killed mid-conversation (due to rolling updates, OOM, or node eviction), the in-flight run is lost. The user sees a frozen chat with no way to resume. There is no mechanism to track active runs, persist their state, or recover them on a replacement pod.
Expected Behavior
When a pod is killed mid-run:
Proposed Solution
Add a lifecycle state persistence engine (
lifecycle.py) that:FOR UPDATE SKIP LOCKEDto prevent duplicate processing across replicas, then re-enqueues through the Aegra worker executorFiles to modify
startup.py— callresume_interrupted_runson pod startupshutdown.py— callpersist_inflight_runsduring graceful shutdowngraph.py— integrate lifecycle tracking (register, update, deregister)Acceptance Criteria
FOR UPDATE SKIP LOCKED)References