[Serve] Fix proxy state crash on ActorUnschedulableError during RayService incremental upgrade - #65076
[Serve] Fix proxy state crash on ActorUnschedulableError during RayService incremental upgrade#65076ryanaoleary wants to merge 8 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request improves the robustness of the proxy actor shutdown and health check logic in proxy_state.py by handling ActorUnschedulableError when a node dies during creation, and wrapping shutdown and kill operations in try-except blocks. The review feedback suggests avoiding redundant ray.kill calls when the actor is already shut down, and using the imported ActorUnschedulableError directly instead of its fully qualified name.
jeffreywang88
left a comment
There was a problem hiding this comment.
great find! can we add some tests?
|
@ryanaoleary please rebase your PR after #64403 merged. your covers the kill case as well which is worth fixing. |
this is true? why should the new cluster restore its state from old clusters checkpoint? that sounds like a design flow in RayService incremental upgrade no? |
My understanding is that since the new, upgraded RayCluster points to the same Redis as the old RayCluster (which is still serving traffic), it restores the old actor table and state from GCS on the new cluster as though it's recovering from a crash. When it restores the old cluster's Proxy Actors, it uses their original node IDs with a I think you're right that the main flaw is with KubeRay. It shouldn't load the old Proxy actors into the new cluster during an upgrade, and instead should be aware that it's a migration, not a recovery from a crash. I think the simplest way to achieve this would be for the upgraded cluster to not inherit the same Redis name/namespace and instead start from a fresh slate for the upgraded RayCluster. I think this PR is still worth adding though to gracefully handle garbage collecting unschedulable actors without crashing the controller. Edit: I think if users don't set |
Signed-off-by: Ryan O'Leary <ryanaoleary@google.com>
Signed-off-by: Ryan O'Leary <ryanaoleary@google.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Ryan O'Leary <113500783+ryanaoleary@users.noreply.github.com>
Signed-off-by: Ryan O'Leary <ryanaoleary@google.com>
cbcce24 to
4f687e1
Compare
|
Rebased on master and added test coverage |
|
related KubeRay PR: ray-project/kuberay#5052 |
Signed-off-by: Ryan O'Leary <ryanaoleary@google.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Reviewed by Cursor Bugbot for commit b61d0b6. Configure here.
|
I made a couple changes in b61d0b6 besides removing the mocks from tests, these are:
|
…avoid spam Signed-off-by: Ryan O'Leary <ryanaoleary@google.com>
Signed-off-by: Ryan O'Leary <ryanaoleary@google.com>

Description
Fixes an issue where the Ray Serve controller loop crashes with an uncaught
ActorUnschedulableErrorwhen attempting to shut down a proxy pinned to a dead or non-existant node. This PR wraps the shutdownray.get()call in atry...exceptblock, allowing the controller to gracefully clean up the dead proxy handle.When does this bug occur?
This race condition occurs when a proxy actor is created on a node that dies while the creation is still pending. It can be seen during RayService incremental upgrades when GCS Fault Tolerance with Redis is enabled:
PENDING_CREATION.alive_node_idsand callsshutdown()on the pending proxy handle.ray.get()throws anActorUnschedulableError, crashing the controller.Related issues
This issue was brought up in discussion in the KubeRay slack channel.
Additional information