mirror of
https://github.com/wassname/ray.git
synced 2026-06-30 10:33:24 +08:00
Add actor.__ray_kill__() to terminate actors immediately (#6523)
This commit is contained in:
@@ -1034,6 +1034,14 @@ cdef class CoreWorker:
|
||||
|
||||
return VectorToObjectIDs(return_ids)
|
||||
|
||||
def kill_actor(self, ActorID actor_id):
|
||||
cdef:
|
||||
CActorID c_actor_id = actor_id.native()
|
||||
|
||||
with nogil:
|
||||
check_status(self.core_worker.get().KillActor(
|
||||
c_actor_id))
|
||||
|
||||
def resource_ids(self):
|
||||
cdef:
|
||||
ResourceMappingType resource_mapping = (
|
||||
|
||||
+15
-1
@@ -642,7 +642,7 @@ class ActorHandle(object):
|
||||
self._actor_id.hex())
|
||||
|
||||
def __del__(self):
|
||||
"""Kill the worker that is running this actor."""
|
||||
"""Terminate the worker that is running this actor."""
|
||||
# TODO(swang): Also clean up forked actor handles.
|
||||
# Kill the worker if this is the original actor handle, created
|
||||
# with Class.remote(). TODO(rkn): Even without passing handles around,
|
||||
@@ -671,6 +671,20 @@ class ActorHandle(object):
|
||||
finally:
|
||||
self.__ray_terminate__._actor_hard_ref = None
|
||||
|
||||
def __ray_kill__(self):
|
||||
"""Kill the actor that this actor handle refers to immediately.
|
||||
|
||||
This will cause any outstanding tasks submitted to the actor to fail
|
||||
and the actor to exit in the same way as if it crashed. In general,
|
||||
you should prefer to just delete the actor handle and let it clean up
|
||||
gracefull.
|
||||
|
||||
Returns:
|
||||
None.
|
||||
"""
|
||||
worker = ray.worker.get_global_worker()
|
||||
worker.core_worker.kill_actor(self._ray_actor_id)
|
||||
|
||||
@property
|
||||
def _actor_id(self):
|
||||
return self._ray_actor_id
|
||||
|
||||
@@ -98,6 +98,7 @@ cdef extern from "ray/core_worker/core_worker.h" nogil:
|
||||
const CActorID &actor_id, const CRayFunction &function,
|
||||
const c_vector[CTaskArg] &args, const CTaskOptions &options,
|
||||
c_vector[CObjectID] *return_ids)
|
||||
CRayStatus KillActor(const CActorID &actor_id)
|
||||
|
||||
unique_ptr[CProfileEvent] CreateProfileEvent(
|
||||
const c_string &event_type)
|
||||
|
||||
@@ -1431,6 +1431,22 @@ ray.get(actor.ping.remote())
|
||||
assert ray.get(detached_actor.ping.remote()) == "pong"
|
||||
|
||||
|
||||
def test_kill(ray_start_regular):
|
||||
@ray.remote
|
||||
class Actor(object):
|
||||
def hang(self):
|
||||
# Never returns.
|
||||
ray.get(ray.ObjectID.from_random())
|
||||
|
||||
actor = Actor.remote()
|
||||
result = actor.hang.remote()
|
||||
ready, _ = ray.wait([result], timeout=0.1)
|
||||
assert len(ready) == 0
|
||||
actor.__ray_kill__()
|
||||
with pytest.raises(ray.exceptions.RayActorError):
|
||||
ray.get(result, timeout=1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
@@ -1746,6 +1746,28 @@ def remote(*args, **kwargs):
|
||||
class Foo(object):
|
||||
def method(self):
|
||||
return 1
|
||||
|
||||
Remote task and actor objects returned by @ray.remote can also be
|
||||
dynamically modified with the same arguments as above using
|
||||
``.options()`` as follows:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ray.remote(num_gpus=1, max_calls=1, num_return_vals=2)
|
||||
def f():
|
||||
return 1, 2
|
||||
g = f.options(num_gpus=2, max_calls=None)
|
||||
|
||||
@ray.remote(num_cpus=2, resources={"CustomResource": 1})
|
||||
class Foo(object):
|
||||
def method(self):
|
||||
return 1
|
||||
Bar = Foo.options(num_cpus=1, resources=None)
|
||||
|
||||
Running remote actors will be terminated when the actor handle to them
|
||||
in Python is deleted, which will cause them to complete any outstanding
|
||||
work and then shut down. If you want to kill them immediately, you can
|
||||
also call ``actor_handle.__ray_kill__()``.
|
||||
"""
|
||||
worker = get_global_worker()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user