fix: Use final_info.status instead of hardcoded EXITED - #842
Conversation
There was a problem hiding this comment.
Correct fix. Verified the two code paths:
-
Normal exit (
wait_for_containersucceeds): returnsContainerInfo(status=EXITED), sofinal_info.statusisEXITED— identical to the old hardcoded value. No behavior change. -
Lost container (
ContainerNotFoundError/ContainerOperationError): exception handler synthesizesContainerInfo(status=FAILED), sofinal_info.statusisFAILED— now correctly persisted instead of being overwritten toEXITED.
One minor pre-existing observation (non-blocking): ci.exited_at = datetime.utcnow() on line 3418 discards final_info.exited_at (which is already set by both the normal and exception paths). Not a bug — the timestamp difference is negligible — but using final_info.exited_at would be more consistent with the pattern this fix establishes.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Agreed. Updated ci.exited_at to use final_info.exited_at instead of datetime.utcnow() for consistency with the final_info pattern. Both the normal exit path and the exception handler already set exited_at on final_info, so this is a clean change.
Pushed in 601d475.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Re-review of changes since 30aaf3d (commit 601d475)
The new commit cleanly addresses the non-blocking suggestion from my previous review.
Change reviewed: ci.exited_at = datetime.utcnow() → ci.exited_at = final_info.exited_at
Verification:
wait_for_container(docker_client.py:478) setsexited_at=datetime.utcnow()on normal exit.- The exception handler (pipelines.py:3393) sets
exited_at=datetime.utcnow()on container loss. - Both paths guarantee
final_info.exited_atis populated before it's read. - No other files were modified; the change is scoped to the single suggestion.
All three fields in the container status update block now consistently read from final_info (status, exited_at, exit_code). No issues found.
Previous approval stands.
— Authored by egg
…-spawn-wait-status: resolve conflict in orchestrator/routes/pipelines.py
This comment has been minimized.
This comment has been minimized.
Conflict Resolution SummaryResolved merge conflicts with
DetailsThe base branch merged PR #841 ( The conflict was in the
Resolved by keeping the PR branch's version since all three fields ( Verification
— Authored by egg |
This comment has been minimized.
This comment has been minimized.
f18e236
into
fix/orphaned-container-state-reconciliation
There was a problem hiding this comment.
Re-review: No new issues (merge commit only)
The only commit since my last review (601d475) is the merge conflict resolution (5ad213e), which merged fix/orphaned-container-state-reconciliation into this branch.
Delta: Zero diff on orchestrator/routes/pipelines.py between 601d475 and the merge commit. The conflict was resolved by keeping the PR branch's final_info.exited_at — consistent with the suggestion from the initial review.
Previous feedback status: The non-blocking suggestion (use final_info.exited_at instead of datetime.utcnow()) was addressed in 601d475 and preserved through the merge. All three fields (status, exited_at, exit_code) now consistently read from final_info.
No new issues introduced. Previous approval stands.
— Authored by egg
|
egg review completed. View run logs 5 previous review(s) hidden. |
* fix: Handle orphaned container state on orchestrator restart
On restart, pipelines left in RUNNING status with dead containers are now
detected and marked FAILED so operators can restart them via the existing
POST /pipelines/{id}/start endpoint.
- Add startup_reconciliation.py with reconcile_stale_containers() that
compares persisted RUNNING agents against live Docker containers and
marks any missing ones FAILED
- Call reconciliation in api.py main() before serving, logging the
recovery count
- Wrap wait_for_container() in _spawn_and_wait() with a try/except for
ContainerNotFoundError/ContainerOperationError, synthesizing a failed
ContainerInfo so the agent is always marked FAILED even if Docker loses
the container mid-wait
- Add 11 unit tests covering all reconciliation paths
Fixes issue-738.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: Use final_info.status instead of hardcoded EXITED in _spawn_and_wait (#841)
The state-update block after wait_for_container unconditionally set
container status to EXITED, overwriting the FAILED status set by the
exception handler for lost containers. Use final_info.status so the
persisted state correctly reflects FAILED when a container is lost
mid-wait.
Co-authored-by: egg-reviewer[bot] <261018737+egg-reviewer[bot]@users.noreply.github.com>
* fix: Use final_info.status instead of hardcoded EXITED (#842)
* fix: Use final_info.status instead of hardcoded EXITED in _spawn_and_wait
* Use final_info.exited_at for consistency with final_info pattern
---------
Co-authored-by: james-in-a-box[bot] <246424927+james-in-a-box[bot]@users.noreply.github.com>
Co-authored-by: egg-reviewer[bot] <261018737+egg-reviewer[bot]@users.noreply.github.com>
Co-authored-by: jwbron <8340608+jwbron@users.noreply.github.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: james-in-a-box[bot] <246424927+james-in-a-box[bot]@users.noreply.github.com>
Co-authored-by: egg-reviewer[bot] <261018737+egg-reviewer[bot]@users.noreply.github.com>
Fix container status overwrite in _spawn_and_wait
When
wait_for_container()raisesContainerNotFoundErrororContainerOperationError, the exception handler correctly synthesizes aContainerInfowithstatus=FAILED. However, the state-update block atline 3416 unconditionally overwrote the persisted status to
EXITED,ignoring
final_info.status.Changed
ci.status = ContainerStatus.EXITED→ci.status = final_info.statusso the persisted state correctly reflects
FAILEDfor lost containers andEXITEDfor normal exits.Also removes
🤖 Generated with [Claude Code]from PR #839 description(gateway blocks this edit since the PR was authored by
jwbron— the lineshould be removed manually before merge).
Addresses review feedback on PR #839.
Issue: none
Test plan:
Authored-by: egg