Skip to content

[Serve][1/n] Add deployment-scoped actors (deployment_actors) to Ray Serve#61566

Draft
abrarsheikh wants to merge 3 commits intomasterfrom
61464-abrar-actors
Draft

[Serve][1/n] Add deployment-scoped actors (deployment_actors) to Ray Serve#61566
abrarsheikh wants to merge 3 commits intomasterfrom
61464-abrar-actors

Conversation

@abrarsheikh
Copy link
Contributor

@abrarsheikh abrarsheikh commented Mar 8, 2026

  • Introduce DeploymentActorConfig, a new config for declaring long-lived, deployment-scoped Ray actors that are shared across all replicas of a deployment and managed by the Serve controller.
  • Add serve.get_deployment_actor(name) API for replicas to obtain a handle to a deployment-scoped actor by name.
  • Wire deployment_actors through the full config stack: protobuf schema, DeploymentConfig (with proto serialization roundtrip), DeploymentSchema, Deployment.options(), and the declarative ServeDeploySchema path.
  • Include deployment_actors in get_app_code_version so that changes to deployment actor configs trigger redeployment in the declarative API.

Test plan

  • Unit: test_config.pyDeploymentActorConfig creation, proto roundtrip, duplicate-name validation, import-path resolution.
  • Unit: test_schema.py — schema validation (dict, unset, None), deployment_to_schema/schema_to_deployment roundtrip, dict-based schema, get_app_code_version hash sensitivity.
  • Unit: test_common.pyget_deployment_actor_name deterministic naming.
  • Integration: test_api.pydeployment_actors as dict and DeploymentActorConfig object via Python API (serve.run); get_deployment_actor error outside replica.
  • Integration: test_deploy_app.py — declarative API (client.deploy_apps with ServeDeploySchema) with deployment_actors, verifying app reaches RUNNING and serves traffic.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces deployment_actors, a new feature for declaring long-lived, deployment-scoped Ray actors. The changes are well-integrated across the Serve stack, from configuration and protobuf schemas to the public API, and include comprehensive tests. The implementation is solid, but I have one suggestion to improve the performance of the duplicate name validation logic.

@abrarsheikh abrarsheikh added the go add ONLY when ready to merge, run all tests label Mar 8, 2026
Signed-off-by: abrar <abrar@anyscale.com>
Signed-off-by: abrar <abrar@anyscale.com>
Copy link
Contributor

@jeffreywang-anyscale jeffreywang-anyscale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

went through a first pass. need a deeper look into deployment_state.py and tests.

Comment on lines +160 to +161
// Unique name for this actor within the deployment.
string name = 5;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: order fields by value

Comment on lines +497 to +498
def _loads(b):
return cloudpickle.loads(b) if b else None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: move this out of the for loop

self.tree = serve.get_deployment_actor("prefix_tree")

def __call__(self, request):
ray.get(self.tree.insert.remote(request.text))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: PrefixTreeActor in this docstring example doesn't implement insert().

def _serialize_actor_class(self) -> None:
"""Import and serialize the actor class with pickle-by-value."""
actor_class = self.actor_class
if isinstance(actor_class, str):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this path is not possible because the caller on line 990 only enters when self.actor_class is not a string.

"""
internal_context = _get_internal_replica_context()
if internal_context is None:
from ray.serve.exceptions import RayServeException
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is already imported at the beginning of the file

self.tree = serve.get_deployment_actor("prefix_tree")

def __call__(self, request):
ray.get(self.tree.insert.remote(request.text))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same nit here: insert() is not implemented by this docstring example

Comment on lines +357 to +358
class DeploymentActors(DeploymentActorContainer):
"""Backward-compatible alias for DeploymentActorContainer."""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason why we need backward compatibility for DeploymentActorContainer? isn't it first introduced in this PR?

self._versions_ready.discard(code_ver)
self._wrappers_by_version.pop(code_ver, None)

if versions_to_keep is None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible for us to leak pending actors under the following situation?

  1. first version is deployed
  2. second version arrives while the first version is in PENDING state
  3. now, the target version is the second version and added to versions_to_keep

throughout the deployment lifetime, the actors associated with the first version are leaked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

go add ONLY when ready to merge, run all tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants