diff --git a/python/ray/actor.py b/python/ray/actor.py index 1df3b8706..499cd1eac 100644 --- a/python/ray/actor.py +++ b/python/ray/actor.py @@ -12,6 +12,7 @@ from ray.util.placement_group import ( from ray import ActorClassID, Language from ray._raylet import PythonFunctionDescriptor +from ray._private.client_mode_hook import client_mode_hook from ray import cross_language from ray.util.inspect import ( is_function_or_method, @@ -22,6 +23,7 @@ from ray.util.inspect import ( logger = logging.getLogger(__name__) +@client_mode_hook def method(*args, **kwargs): """Annotate an actor method. diff --git a/python/ray/tests/test_actor.py b/python/ray/tests/test_actor.py index c4faa6e09..1aafcd04f 100644 --- a/python/ray/tests/test_actor.py +++ b/python/ray/tests/test_actor.py @@ -650,7 +650,6 @@ def test_actor_inheritance(ray_start_regular_shared): pass -@pytest.mark.skipif(client_test_enabled(), reason="ray.method unimplemented") def test_multiple_return_values(ray_start_regular_shared): @ray.remote class Foo: diff --git a/python/ray/util/client/api.py b/python/ray/util/client/api.py index 66a8d00d5..e8bcb1a2b 100644 --- a/python/ray/util/client/api.py +++ b/python/ray/util/client/api.py @@ -173,6 +173,27 @@ class ClientAPI: return self.worker.get_cluster_info( ray_client_pb2.ClusterInfoType.NODES) + def method(self, num_returns=1): + """Annotate an actor method + + Args: + num_returns: The number of object refs that should be returned by + invocations of this actor method. + """ + + # NOTE: So this follows the same logic as in ray/actor.py::method() + # The reason to duplicate it here is to simplify the client mode + # redirection logic. As the annotated method gets pickled and sent to + # the server from the client it carries this private variable, it + # activates the same logic on the server side; so there's no need to + # pass anything else. It's inside the class definition that becomes an + # actor. Similar annotations would follow the same way. + def annotate_method(method): + method.__ray_num_returns__ = num_returns + return method + + return annotate_method + def cluster_resources(self): """Get the current total cluster resources. diff --git a/python/ray/util/client/common.py b/python/ray/util/client/common.py index 7b77f3c30..2bcd14f3f 100644 --- a/python/ray/util/client/common.py +++ b/python/ray/util/client/common.py @@ -181,10 +181,6 @@ class ClientActorHandle(ClientStub): Args: actor_ref: A reference to the running actor given to the client. This is a serialized version of the actual handle as an opaque token. - actor_class: A reference to the ClientActorClass that this actor was - instantiated from. - _real_actor_handle: Cached copy of the Raylet-side - ray.actor.ActorHandle contained in the actor_id ref. """ def __init__(self, actor_ref: ClientActorRef):