Fix actor garbage collection by breaking cyclic references (#1064)

* Fix bug in wait_for_pid_to_exit, add test for actor deletion.

* Fix actor garbage collection by breaking cyclic references

* Add test for calling actor method immediately after actor creation.

* Fix bug, must dispatch tasks when workers are killed.

* Fix python test

* Fix cyclic reference problem by creating ActorMethod objects on the fly.

* Try simply increasing the time allowed for many_drivers_test.py.
This commit is contained in:
Stephanie Wang
2017-10-05 00:55:33 -07:00
committed by Robert Nishihara
parent 971becc905
commit aebe9f9374
5 changed files with 66 additions and 22 deletions
+13 -12
View File
@@ -251,6 +251,8 @@ def make_actor(cls, num_cpus, num_gpus, checkpoint_interval):
# constructor.
exported = []
# Create objects to wrap method invocations. This is done so that we can
# invoke methods with actor.method.remote() instead of actor.method().
class ActorMethod(object):
def __init__(self, actor, method_name, method_signature):
self.actor = actor
@@ -307,14 +309,6 @@ def make_actor(cls, num_cpus, num_gpus, checkpoint_interval):
self._ray_method_signatures[k] = signature.extract_signature(
v, ignore_first=True)
# Create objects to wrap method invocations. This is done so that
# we can invoke methods with actor.method.remote() instead of
# actor.method().
self._actor_method_invokers = dict()
for k, v in self._ray_actor_methods.items():
self._actor_method_invokers[k] = ActorMethod(
self, k, self._ray_method_signatures[k])
# Do not export the actor class or the actor if run in PYTHON_MODE
# Instead, instantiate the actor locally and add it to
# global_worker's dictionary
@@ -390,10 +384,17 @@ def make_actor(cls, num_cpus, num_gpus, checkpoint_interval):
"_actor_method_call"]:
return object.__getattribute__(self, attr)
if attr in self._ray_actor_methods.keys():
return self._actor_method_invokers[attr]
# There is no method with this name, so raise an exception.
raise AttributeError("'{}' Actor object has no attribute '{}'"
.format(Class, attr))
# We create the ActorMethod on the fly here so that the
# ActorHandle doesn't need a reference to the ActorMethod. The
# ActorMethod has a reference to the ActorHandle and this was
# causing cyclic references which were prevent object
# deallocation from behaving in a predictable manner.
return ActorMethod(self, attr,
self._ray_method_signatures[attr])
else:
# There is no method with this name, so raise an exception.
raise AttributeError("'{}' Actor object has no attribute '{}'"
.format(Class, attr))
def __repr__(self):
return "Actor(" + self._ray_actor_id.hex() + ")"
+1
View File
@@ -118,6 +118,7 @@ def _pid_alive(pid):
"""
try:
os.kill(pid, 0)
return True
except OSError:
return False