Fix: do not treat actor task as failed if the actor will be reconstructed (#3736)

This commit is contained in:
Hao Chen
2019-01-24 15:28:44 +08:00
committed by Robert Nishihara
parent 04ec47cbd4
commit bfcf254e52
3 changed files with 90 additions and 41 deletions
+15 -13
View File
@@ -2215,30 +2215,32 @@ def test_actor_reconstruction(ray_start_regular):
def __init__(self):
self.value = 0
def increase(self):
def increase(self, delay=0):
time.sleep(delay)
self.value += 1
return self.value
def get_pid(self):
return os.getpid()
def kill_actor(actor):
"""Kill actor process."""
pid = ray.get(actor.get_pid.remote())
os.kill(pid, signal.SIGKILL)
time.sleep(1)
actor = ReconstructableActor.remote()
pid = ray.get(actor.get_pid.remote())
# Call increase 3 times
for _ in range(3):
ray.get(actor.increase.remote())
# kill actor process
kill_actor(actor)
# Call increase again.
# Check that actor is reconstructed and value is 4.
assert ray.get(actor.increase.remote()) == 4
# Call increase again with some delay.
result = actor.increase.remote(delay=0.5)
# Sleep some time to wait for the above task to start execution.
time.sleep(0.2)
# Kill actor process, while the above task is still being executed.
os.kill(pid, signal.SIGKILL)
# Check that the above task didn't fail and the actor is reconstructed.
assert ray.get(result) == 4
# Check that we can still call the actor.
assert ray.get(actor.increase.remote()) == 5
# kill actor process one more time.
kill_actor(actor)
pid = ray.get(actor.get_pid.remote())
os.kill(pid, signal.SIGKILL)
# The actor has exceeded max reconstructions, and this task should fail.
with pytest.raises(ray.worker.RayTaskError):
ray.get(actor.increase.remote())
+38
View File
@@ -416,3 +416,41 @@ print("success")
for i in range(2):
out = run_string_as_driver(driver_script)
assert "success" in out
def test_driver_exiting_when_worker_blocked(ray_start_head):
# This test will create some drivers that submit some tasks and then
# exit without waiting for the tasks to complete.
redis_address = ray_start_head
ray.init(redis_address=redis_address)
# Define a driver that creates an actor and exits.
driver_script = """
import time
import ray
ray.init(redis_address="{}")
@ray.remote
def f():
time.sleep(10**6)
@ray.remote
def g():
ray.get(f.remote())
g.remote()
time.sleep(1)
print("success")
""".format(redis_address)
# Create some drivers and let them exit and make sure everything is
# still alive.
for _ in range(3):
out = run_string_as_driver(driver_script)
# Make sure the first driver ran to completion.
assert "success" in out
@ray.remote
def f():
return 1
# Make sure we can still talk with the raylet.
ray.get(f.remote())