mirror of
https://github.com/wassname/ray.git
synced 2026-07-05 19:41:13 +08:00
Remove actor handle IDs (#5889)
* Remove actor handle ID from main ActorHandle constructor * Set the actor caller ID when calling submit task instead of in the actor handle * Remove ActorHandle::Fork, remove actor handle ID from protobuf * Make inner actor handle const, remove new_actor_handles * Move caller ID into the common task spec, start refactoring raylet * Some fixes for forking actor handles * Store ActorHandle state in CoreWorker, only expose actor ID to Python * Remove some unused fields * lint * doc * fix merge * Remove ActorHandleID from python/cpp * doc * Fix core worker test * Move actor table subscription to CoreWorker, reset actor handles on actor failure * lint * Remove GCS client from direct actor * fix tests * Fix * Fix tests for raylet codepath * Fix local mode * Fix multithreaded test * Fix AsyncSubscribe issue... * doc * fix serve * Revert bazel
This commit is contained in:
@@ -65,7 +65,6 @@ except ImportError as e:
|
||||
from ray._raylet import (
|
||||
ActorCheckpointID,
|
||||
ActorClassID,
|
||||
ActorHandleID,
|
||||
ActorID,
|
||||
ClientID,
|
||||
Config as _Config,
|
||||
@@ -154,7 +153,6 @@ __all__ = [
|
||||
__all__ += [
|
||||
"ActorCheckpointID",
|
||||
"ActorClassID",
|
||||
"ActorHandleID",
|
||||
"ActorID",
|
||||
"ClientID",
|
||||
"JobID",
|
||||
|
||||
+43
-5
@@ -23,6 +23,7 @@ from libcpp.vector cimport vector as c_vector
|
||||
from cython.operator import dereference, postincrement
|
||||
|
||||
from ray.includes.common cimport (
|
||||
CActorHandle,
|
||||
CLanguage,
|
||||
CRayObject,
|
||||
CRayStatus,
|
||||
@@ -432,6 +433,13 @@ cdef class CoreWorker:
|
||||
with nogil:
|
||||
self.core_worker.get().SetCurrentTaskId(c_task_id)
|
||||
|
||||
def set_actor_id(self, ActorID actor_id):
|
||||
cdef:
|
||||
CActorID c_actor_id = actor_id.native()
|
||||
|
||||
with nogil:
|
||||
self.core_worker.get().SetActorId(c_actor_id)
|
||||
|
||||
def get_current_task_id(self):
|
||||
return TaskID(self.core_worker.get().GetCurrentTaskId().Binary())
|
||||
|
||||
@@ -622,6 +630,7 @@ cdef class CoreWorker:
|
||||
CRayFunction ray_function
|
||||
c_vector[CTaskArg] args_vector
|
||||
c_vector[CObjectID] return_ids
|
||||
CTaskID caller_id
|
||||
|
||||
with profiling.profile("submit_task"):
|
||||
prepare_resources(resources, &c_resources)
|
||||
@@ -629,9 +638,11 @@ cdef class CoreWorker:
|
||||
ray_function = CRayFunction(
|
||||
LANGUAGE_PYTHON, string_vector_from_list(function_descriptor))
|
||||
prepare_args(args, &args_vector)
|
||||
caller_id = self.core_worker.get().GetCallerId()
|
||||
|
||||
with nogil:
|
||||
check_status(self.core_worker.get().Tasks().SubmitTask(
|
||||
caller_id,
|
||||
ray_function, args_vector, task_options, &return_ids))
|
||||
|
||||
return VectorToObjectIDs(return_ids)
|
||||
@@ -643,12 +654,13 @@ cdef class CoreWorker:
|
||||
resources,
|
||||
placement_resources):
|
||||
cdef:
|
||||
ActorHandle actor_handle = ActorHandle.__new__(ActorHandle)
|
||||
unique_ptr[CActorHandle] actor_handle
|
||||
CRayFunction ray_function
|
||||
c_vector[CTaskArg] args_vector
|
||||
c_vector[c_string] dynamic_worker_options
|
||||
unordered_map[c_string, double] c_resources
|
||||
unordered_map[c_string, double] c_placement_resources
|
||||
CTaskID caller_id
|
||||
|
||||
with profiling.profile("submit_task"):
|
||||
prepare_resources(resources, &c_resources)
|
||||
@@ -656,30 +668,38 @@ cdef class CoreWorker:
|
||||
ray_function = CRayFunction(
|
||||
LANGUAGE_PYTHON, string_vector_from_list(function_descriptor))
|
||||
prepare_args(args, &args_vector)
|
||||
caller_id = self.core_worker.get().GetCallerId()
|
||||
|
||||
with nogil:
|
||||
check_status(self.core_worker.get().Tasks().CreateActor(
|
||||
caller_id,
|
||||
ray_function, args_vector,
|
||||
CActorCreationOptions(
|
||||
max_reconstructions, False, c_resources,
|
||||
c_placement_resources, dynamic_worker_options),
|
||||
&actor_handle.inner))
|
||||
&actor_handle))
|
||||
|
||||
return actor_handle
|
||||
actor_id = ActorID(actor_handle.get().GetActorID().Binary())
|
||||
inserted = self.core_worker.get().AddActorHandle(
|
||||
move(actor_handle))
|
||||
assert inserted, "Actor {} already exists".format(actor_id)
|
||||
return actor_id
|
||||
|
||||
def submit_actor_task(self,
|
||||
ActorHandle handle,
|
||||
ActorID actor_id,
|
||||
function_descriptor,
|
||||
args,
|
||||
int num_return_vals,
|
||||
resources):
|
||||
|
||||
cdef:
|
||||
CActorID c_actor_id = actor_id.native()
|
||||
unordered_map[c_string, double] c_resources
|
||||
CTaskOptions task_options
|
||||
CRayFunction ray_function
|
||||
c_vector[CTaskArg] args_vector
|
||||
c_vector[CObjectID] return_ids
|
||||
CTaskID caller_id
|
||||
|
||||
with profiling.profile("submit_task"):
|
||||
prepare_resources(resources, &c_resources)
|
||||
@@ -687,10 +707,13 @@ cdef class CoreWorker:
|
||||
ray_function = CRayFunction(
|
||||
LANGUAGE_PYTHON, string_vector_from_list(function_descriptor))
|
||||
prepare_args(args, &args_vector)
|
||||
caller_id = self.core_worker.get().GetCallerId()
|
||||
|
||||
with nogil:
|
||||
check_status(self.core_worker.get().Tasks().SubmitActorTask(
|
||||
handle.inner.get()[0], ray_function,
|
||||
caller_id,
|
||||
self.core_worker.get().GetActorHandle(c_actor_id),
|
||||
ray_function,
|
||||
args_vector, task_options, &return_ids))
|
||||
|
||||
return VectorToObjectIDs(return_ids)
|
||||
@@ -702,3 +725,18 @@ cdef class CoreWorker:
|
||||
return ProfileEvent.make(
|
||||
self.core_worker.get().CreateProfileEvent(c_event_type),
|
||||
extra_data)
|
||||
|
||||
def deserialize_actor_handle(self, c_string bytes):
|
||||
cdef:
|
||||
unique_ptr[CActorHandle] actor_handle
|
||||
actor_handle.reset(new CActorHandle(bytes))
|
||||
actor_id = ActorID(actor_handle.get().GetActorID().Binary())
|
||||
self.core_worker.get().AddActorHandle(move(actor_handle))
|
||||
return actor_id
|
||||
|
||||
def serialize_actor_handle(self, ActorID actor_id):
|
||||
cdef:
|
||||
CActorID c_actor_id = actor_id.native()
|
||||
c_string output
|
||||
self.core_worker.get().GetActorHandle(c_actor_id).Serialize(&output)
|
||||
return output
|
||||
|
||||
+19
-20
@@ -16,7 +16,7 @@ import ray.ray_constants as ray_constants
|
||||
import ray._raylet
|
||||
import ray.signature as signature
|
||||
import ray.worker
|
||||
from ray import ActorID, ActorHandleID, ActorClassID, profiling
|
||||
from ray import ActorID, ActorClassID, profiling
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -372,9 +372,6 @@ class ActorClass(object):
|
||||
actor_id = ActorID.from_random()
|
||||
worker.actors[actor_id] = meta.modified_class(
|
||||
*copy.deepcopy(args), **copy.deepcopy(kwargs))
|
||||
core_handle = ray._raylet.ActorHandle(
|
||||
actor_id, ActorHandleID.nil(), worker.current_job_id,
|
||||
function_descriptor.get_function_descriptor_list())
|
||||
else:
|
||||
# Export the actor.
|
||||
if (meta.last_export_session_and_job !=
|
||||
@@ -404,13 +401,13 @@ class ActorClass(object):
|
||||
function_signature = meta.method_signatures[function_name]
|
||||
creation_args = signature.extend_args(function_signature, args,
|
||||
kwargs)
|
||||
core_handle = worker.core_worker.create_actor(
|
||||
actor_id = worker.core_worker.create_actor(
|
||||
function_descriptor.get_function_descriptor_list(),
|
||||
creation_args, meta.max_reconstructions, resources,
|
||||
actor_placement_resources)
|
||||
|
||||
actor_handle = ActorHandle(
|
||||
core_handle,
|
||||
actor_id,
|
||||
meta.modified_class.__module__,
|
||||
meta.class_name,
|
||||
meta.actor_method_names,
|
||||
@@ -436,7 +433,7 @@ class ActorHandle(object):
|
||||
cloudpickle).
|
||||
|
||||
Attributes:
|
||||
_ray_core_handle: Core worker actor handle for this actor.
|
||||
_ray_actor_id: Actor ID.
|
||||
_ray_module_name: The module name of this actor.
|
||||
_ray_actor_method_names: The names of the actor methods.
|
||||
_ray_method_decorators: Optional decorators for the function
|
||||
@@ -454,7 +451,7 @@ class ActorHandle(object):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
core_handle,
|
||||
actor_id,
|
||||
module_name,
|
||||
class_name,
|
||||
actor_method_names,
|
||||
@@ -464,7 +461,7 @@ class ActorHandle(object):
|
||||
actor_method_cpus,
|
||||
session_and_job,
|
||||
original_handle=False):
|
||||
self._ray_core_handle = core_handle
|
||||
self._ray_actor_id = actor_id
|
||||
self._ray_module_name = module_name
|
||||
self._ray_original_handle = original_handle
|
||||
self._ray_actor_method_names = actor_method_names
|
||||
@@ -518,7 +515,7 @@ class ActorHandle(object):
|
||||
function, function_descriptor, args, num_return_vals)
|
||||
else:
|
||||
object_ids = worker.core_worker.submit_actor_task(
|
||||
self._ray_core_handle,
|
||||
self._ray_actor_id,
|
||||
function_descriptor.get_function_descriptor_list(), args,
|
||||
num_return_vals, {"CPU": self._ray_actor_method_cpus})
|
||||
|
||||
@@ -579,8 +576,8 @@ class ActorHandle(object):
|
||||
# and we don't need to send `__ray_terminate__` again.
|
||||
logger.warning(
|
||||
"Actor is garbage collected in the wrong driver." +
|
||||
" Actor id = %s, class name = %s.",
|
||||
self._ray_core_handle.actor_id(), self._ray_class_name)
|
||||
" Actor id = %s, class name = %s.", self._ray_actor_id,
|
||||
self._ray_class_name)
|
||||
return
|
||||
if worker.connected and self._ray_original_handle:
|
||||
# TODO(rkn): Should we be passing in the actor cursor as a
|
||||
@@ -589,11 +586,7 @@ class ActorHandle(object):
|
||||
|
||||
@property
|
||||
def _actor_id(self):
|
||||
return self._ray_core_handle.actor_id()
|
||||
|
||||
@property
|
||||
def _actor_handle_id(self):
|
||||
return self._ray_core_handle.actor_handle_id()
|
||||
return self._ray_actor_id
|
||||
|
||||
def _serialization_helper(self, ray_forking):
|
||||
"""This is defined in order to make pickling work.
|
||||
@@ -605,8 +598,13 @@ class ActorHandle(object):
|
||||
Returns:
|
||||
A dictionary of the information needed to reconstruct the object.
|
||||
"""
|
||||
worker = ray.worker.get_global_worker()
|
||||
worker.check_connected()
|
||||
state = {
|
||||
"core_handle": self._ray_core_handle.fork(ray_forking).to_bytes(),
|
||||
# Local mode just uses the actor ID.
|
||||
"core_handle": worker.core_worker.serialize_actor_handle(
|
||||
self._ray_actor_id)
|
||||
if hasattr(worker, "core_worker") else self._ray_actor_id,
|
||||
"module_name": self._ray_module_name,
|
||||
"class_name": self._ray_class_name,
|
||||
"actor_method_names": self._ray_actor_method_names,
|
||||
@@ -632,8 +630,9 @@ class ActorHandle(object):
|
||||
self.__init__(
|
||||
# TODO(swang): Accessing the worker's current task ID is not
|
||||
# thread-safe.
|
||||
ray._raylet.ActorHandle.from_bytes(state["core_handle"],
|
||||
worker.current_task_id),
|
||||
# Local mode just uses the actor ID.
|
||||
worker.core_worker.deserialize_actor_handle(state["core_handle"])
|
||||
if hasattr(worker, "core_worker") else state["core_handle"],
|
||||
state["module_name"],
|
||||
state["class_name"],
|
||||
state["actor_method_names"],
|
||||
|
||||
@@ -27,11 +27,11 @@ class MetricMonitor:
|
||||
return True
|
||||
|
||||
def add_target(self, target_handle):
|
||||
hex_id = target_handle._ray_core_handle.actor_id().hex()
|
||||
hex_id = target_handle._actor_id.hex()
|
||||
self.actor_handles[hex_id] = target_handle
|
||||
|
||||
def remove_target(self, target_handle):
|
||||
hex_id = target_handle._ray_core_handle.actor_id().hex()
|
||||
hex_id = target_handle._actor_id.hex()
|
||||
self.actor_handles.pop(hex_id)
|
||||
|
||||
def scrape(self):
|
||||
|
||||
@@ -8,7 +8,6 @@ from libcpp.vector cimport vector as c_vector
|
||||
|
||||
from ray.includes.unique_ids cimport (
|
||||
CActorID,
|
||||
CActorHandleID,
|
||||
CJobID,
|
||||
CWorkerID,
|
||||
CObjectID,
|
||||
@@ -199,19 +198,9 @@ cdef extern from "ray/core_worker/task_interface.h" nogil:
|
||||
const c_vector[c_string] &dynamic_worker_options)
|
||||
|
||||
cdef cppclass CActorHandle "ray::ActorHandle":
|
||||
CActorHandle(
|
||||
const CActorID &actor_id, const CActorHandleID &actor_handle_id,
|
||||
const CJobID &job_id, const CObjectID &initial_cursor,
|
||||
const CLanguage actor_language, c_bool is_direct_call,
|
||||
const c_vector[c_string] &actor_creation_task_function_descriptor)
|
||||
CActorHandle(CActorHandle &other, c_bool in_band)
|
||||
CActorHandle(
|
||||
const c_string &serialized, const CTaskID ¤t_task_id)
|
||||
CActorHandle(const c_string &serialized)
|
||||
|
||||
CActorID GetActorID() const
|
||||
CActorHandleID GetActorHandleID() const
|
||||
unique_ptr[CActorHandle] Fork()
|
||||
unique_ptr[CActorHandle] ForkForSerialization()
|
||||
void Serialize(c_string *output)
|
||||
|
||||
cdef extern from "ray/gcs/gcs_client_interface.h" nogil:
|
||||
|
||||
@@ -3,7 +3,6 @@ from libcpp.string cimport string as c_string
|
||||
from libcpp.vector cimport vector as c_vector
|
||||
|
||||
from ray.includes.common cimport (
|
||||
CActorHandle,
|
||||
CGcsClientOptions,
|
||||
)
|
||||
|
||||
@@ -25,48 +24,3 @@ cdef class GcsClientOptions:
|
||||
|
||||
cdef CGcsClientOptions* native(self):
|
||||
return <CGcsClientOptions*>(self.inner.get())
|
||||
|
||||
cdef class ActorHandle:
|
||||
"""Cython wrapper class of C++ `ray::ActorHandle`."""
|
||||
cdef:
|
||||
unique_ptr[CActorHandle] inner
|
||||
|
||||
def __init__(self, ActorID actor_id, ActorHandleID actor_handle_id,
|
||||
JobID job_id, list creation_function_descriptor):
|
||||
cdef:
|
||||
c_vector[c_string] c_descriptor
|
||||
ObjectID cursor = ObjectID.from_random()
|
||||
|
||||
c_descriptor = string_vector_from_list(creation_function_descriptor)
|
||||
self.inner.reset(new CActorHandle(
|
||||
actor_id.native(), actor_handle_id.native(), job_id.native(),
|
||||
cursor.native(), LANGUAGE_PYTHON, False, c_descriptor))
|
||||
|
||||
def fork(self, c_bool ray_forking):
|
||||
cdef:
|
||||
ActorHandle other = ActorHandle.__new__(ActorHandle)
|
||||
if ray_forking:
|
||||
other.inner = self.inner.get().Fork()
|
||||
else:
|
||||
other.inner = self.inner.get().ForkForSerialization()
|
||||
return other
|
||||
|
||||
@staticmethod
|
||||
def from_bytes(c_string bytes, TaskID current_task_id):
|
||||
cdef:
|
||||
ActorHandle self = ActorHandle.__new__(ActorHandle)
|
||||
self.inner.reset(new CActorHandle(bytes, current_task_id.native()))
|
||||
return self
|
||||
|
||||
def to_bytes(self):
|
||||
cdef:
|
||||
c_string output
|
||||
|
||||
self.inner.get().Serialize(&output)
|
||||
return output
|
||||
|
||||
def actor_id(self):
|
||||
return ActorID(self.inner.get().GetActorID().Binary())
|
||||
|
||||
def actor_handle_id(self):
|
||||
return ActorHandleID(self.inner.get().GetActorHandleID().Binary())
|
||||
|
||||
@@ -5,6 +5,7 @@ from libcpp.string cimport string as c_string
|
||||
from libcpp.vector cimport vector as c_vector
|
||||
|
||||
from ray.includes.unique_ids cimport (
|
||||
CActorID,
|
||||
CJobID,
|
||||
CTaskID,
|
||||
CObjectID,
|
||||
@@ -32,13 +33,16 @@ cdef extern from "ray/core_worker/profiling.h" nogil:
|
||||
cdef extern from "ray/core_worker/task_interface.h" namespace "ray" nogil:
|
||||
cdef cppclass CTaskSubmissionInterface "CoreWorkerTaskInterface":
|
||||
CRayStatus SubmitTask(
|
||||
const CTaskID &caller_id,
|
||||
const CRayFunction &function, const c_vector[CTaskArg] &args,
|
||||
const CTaskOptions &options, c_vector[CObjectID] *return_ids)
|
||||
CRayStatus CreateActor(
|
||||
const CTaskID &caller_id,
|
||||
const CRayFunction &function, const c_vector[CTaskArg] &args,
|
||||
const CActorCreationOptions &options,
|
||||
unique_ptr[CActorHandle] *handle)
|
||||
CRayStatus SubmitActorTask(
|
||||
const CTaskID &caller_id,
|
||||
CActorHandle &handle, const CRayFunction &function,
|
||||
const c_vector[CTaskArg] &args, const CTaskOptions &options,
|
||||
c_vector[CObjectID] *return_ids)
|
||||
@@ -87,3 +91,8 @@ cdef extern from "ray/core_worker/core_worker.h" nogil:
|
||||
void SetCurrentJobId(const CJobID &job_id)
|
||||
CTaskID GetCurrentTaskId()
|
||||
void SetCurrentTaskId(const CTaskID &task_id)
|
||||
void SetActorId(const CActorID &actor_id)
|
||||
const CActorID &GetActorId()
|
||||
CTaskID GetCallerId()
|
||||
c_bool AddActorHandle(unique_ptr[CActorHandle] handle)
|
||||
CActorHandle &GetActorHandle(const CActorID &actor_id)
|
||||
|
||||
@@ -10,7 +10,6 @@ from ray.includes.common cimport (
|
||||
ResourceSet,
|
||||
)
|
||||
from ray.includes.unique_ids cimport (
|
||||
CActorHandleID,
|
||||
CActorID,
|
||||
CJobID,
|
||||
CObjectID,
|
||||
@@ -71,10 +70,8 @@ cdef extern from "ray/common/task/task_spec.h" nogil:
|
||||
CObjectID PreviousActorTaskDummyObjectId() const
|
||||
uint64_t MaxActorReconstructions() const
|
||||
CActorID ActorId() const
|
||||
CActorHandleID ActorHandleId() const
|
||||
uint64_t ActorCounter() const
|
||||
CObjectID ActorDummyObject() const
|
||||
c_vector[CActorHandleID] NewActorHandles() const
|
||||
|
||||
|
||||
cdef extern from "ray/common/task/task_execution_spec.h" nogil:
|
||||
|
||||
@@ -68,11 +68,6 @@ cdef extern from "ray/common/id.h" namespace "ray" nogil:
|
||||
CActorID Of(CJobID job_id, CTaskID parent_task_id,
|
||||
int64_t parent_task_counter)
|
||||
|
||||
cdef cppclass CActorHandleID "ray::ActorHandleID"(CUniqueID):
|
||||
|
||||
@staticmethod
|
||||
CActorHandleID FromBinary(const c_string &binary)
|
||||
|
||||
cdef cppclass CClientID "ray::ClientID"(CUniqueID):
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -11,7 +11,6 @@ import os
|
||||
from ray.includes.unique_ids cimport (
|
||||
CActorCheckpointID,
|
||||
CActorClassID,
|
||||
CActorHandleID,
|
||||
CActorID,
|
||||
CClientID,
|
||||
CConfigID,
|
||||
@@ -343,16 +342,6 @@ cdef class ActorID(BaseID):
|
||||
return self.data.Hash()
|
||||
|
||||
|
||||
cdef class ActorHandleID(UniqueID):
|
||||
|
||||
def __init__(self, id):
|
||||
check_id(id)
|
||||
self.data = CActorHandleID.FromBinary(<c_string>id)
|
||||
|
||||
cdef CActorHandleID native(self):
|
||||
return <CActorHandleID>self.data
|
||||
|
||||
|
||||
cdef class ActorCheckpointID(UniqueID):
|
||||
|
||||
def __init__(self, id):
|
||||
@@ -385,7 +374,6 @@ cdef class ActorClassID(UniqueID):
|
||||
_ID_TYPES = [
|
||||
ActorCheckpointID,
|
||||
ActorClassID,
|
||||
ActorHandleID,
|
||||
ActorID,
|
||||
ClientID,
|
||||
JobID,
|
||||
|
||||
@@ -1447,14 +1447,14 @@ def test_multithreading(ray_start_2_cpus):
|
||||
time.sleep(delay_ms / 1000.0)
|
||||
return value
|
||||
|
||||
@ray.remote
|
||||
class Echo(object):
|
||||
def echo(self, value):
|
||||
return value
|
||||
|
||||
def test_api_in_multi_threads():
|
||||
"""Test using Ray api in multiple threads."""
|
||||
|
||||
@ray.remote
|
||||
class Echo(object):
|
||||
def echo(self, value):
|
||||
return value
|
||||
|
||||
# Test calling remote functions in multiple threads.
|
||||
def test_remote_call():
|
||||
value = random.randint(0, 1000000)
|
||||
|
||||
@@ -867,7 +867,9 @@ class Worker(object):
|
||||
# TODO(rkn): It would be preferable for actor creation tasks to share
|
||||
# more of the code path with regular task execution.
|
||||
if task.is_actor_creation_task():
|
||||
# TODO: Remove Worker.actor_id and just use CoreWorker.GetActorId.
|
||||
self.actor_id = task.actor_creation_id()
|
||||
self.core_worker.set_actor_id(task.actor_creation_id())
|
||||
self.actor_creation_task_id = task.task_id()
|
||||
actor_class = self.function_actor_manager.load_actor_class(
|
||||
job_id, function_descriptor)
|
||||
|
||||
Reference in New Issue
Block a user