mirror of
https://github.com/wassname/ray.git
synced 2026-07-19 11:27:32 +08:00
Simplify imports and exports and provide driver isolation for remote functions. (#288)
* Remove import counter and export counter. * Provide isolation between drivers for remote functions. * Add test for driver function isolation. * Hash source code into function ID to reduce likelihood of collisions. * Fix failure test example. * Replace assertTrue with assertIn to improve failure messages in tests. * Fix failure test.
This commit is contained in:
committed by
Philipp Moritz
parent
883f945db4
commit
88a5b4e77b
+38
-25
@@ -2,10 +2,12 @@ from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import unittest
|
||||
import os
|
||||
import ray
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import unittest
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
from importlib import reload
|
||||
@@ -67,13 +69,13 @@ class TaskStatusTest(unittest.TestCase):
|
||||
result = ray.error_info()
|
||||
self.assertEqual(len(relevant_errors(b"task")), 2)
|
||||
for task in relevant_errors(b"task"):
|
||||
self.assertTrue(b"Test function 1 intentionally failed." in task.get(b"message"))
|
||||
self.assertIn(b"Test function 1 intentionally failed.", task.get(b"message"))
|
||||
|
||||
x = test_functions.throw_exception_fct2.remote()
|
||||
try:
|
||||
ray.get(x)
|
||||
except Exception as e:
|
||||
self.assertTrue("Test function 2 intentionally failed." in str(e))
|
||||
self.assertIn("Test function 2 intentionally failed.", str(e))
|
||||
else:
|
||||
self.assertTrue(False) # ray.get should throw an exception
|
||||
|
||||
@@ -82,7 +84,7 @@ class TaskStatusTest(unittest.TestCase):
|
||||
try:
|
||||
ray.get(ref)
|
||||
except Exception as e:
|
||||
self.assertTrue("Test function 3 intentionally failed." in str(e))
|
||||
self.assertIn("Test function 3 intentionally failed.", str(e))
|
||||
else:
|
||||
self.assertTrue(False) # ray.get should throw an exception
|
||||
|
||||
@@ -91,29 +93,40 @@ class TaskStatusTest(unittest.TestCase):
|
||||
def testFailImportingRemoteFunction(self):
|
||||
ray.init(num_workers=2, driver_mode=ray.SILENT_MODE)
|
||||
|
||||
# This example is somewhat contrived. It should be successfully pickled, and
|
||||
# then it should throw an exception when it is unpickled. This may depend a
|
||||
# bit on the specifics of our pickler.
|
||||
def reducer(*args):
|
||||
raise Exception("There is a problem here.")
|
||||
class Foo(object):
|
||||
def __init__(self):
|
||||
self.__name__ = "Foo_object"
|
||||
self.func_doc = ""
|
||||
self.__globals__ = {}
|
||||
def __reduce__(self):
|
||||
return reducer, ()
|
||||
def __call__(self):
|
||||
return
|
||||
f = ray.remote(Foo())
|
||||
# Create the contents of a temporary Python file.
|
||||
temporary_python_file = """
|
||||
def temporary_helper_function():
|
||||
return 1
|
||||
"""
|
||||
|
||||
f = tempfile.NamedTemporaryFile(suffix=".py")
|
||||
f.write(temporary_python_file.encode("ascii"))
|
||||
f.flush()
|
||||
directory = os.path.dirname(f.name)
|
||||
# Get the module name and strip ".py" from the end.
|
||||
module_name = os.path.basename(f.name)[:-3]
|
||||
sys.path.append(directory)
|
||||
module = __import__(module_name)
|
||||
|
||||
# Define a function that closes over this temporary module. This should fail
|
||||
# when it is unpickled.
|
||||
@ray.remote
|
||||
def g():
|
||||
return module.temporary_python_file()
|
||||
|
||||
wait_for_errors(b"register_remote_function", 2)
|
||||
self.assertTrue(b"There is a problem here." in ray.error_info()[0][b"message"])
|
||||
self.assertIn(b"No module named", ray.error_info()[0][b"message"])
|
||||
self.assertIn(b"No module named", ray.error_info()[1][b"message"])
|
||||
|
||||
# Check that if we try to call the function it throws an exception and does
|
||||
# not hang.
|
||||
for _ in range(10):
|
||||
self.assertRaises(Exception, lambda : ray.get(f.remote()))
|
||||
self.assertRaises(Exception, lambda : ray.get(g.remote()))
|
||||
|
||||
f.close()
|
||||
|
||||
# Clean up the junk we added to sys.path.
|
||||
sys.path.pop(-1)
|
||||
ray.worker.cleanup()
|
||||
|
||||
def testFailImportingEnvironmentVariable(self):
|
||||
@@ -128,7 +141,7 @@ class TaskStatusTest(unittest.TestCase):
|
||||
ray.env.foo = ray.EnvironmentVariable(initializer)
|
||||
wait_for_errors(b"register_environment_variable", 2)
|
||||
# Check that the error message is in the task info.
|
||||
self.assertTrue(b"The initializer failed." in ray.error_info()[0][b"message"])
|
||||
self.assertIn(b"The initializer failed.", ray.error_info()[0][b"message"])
|
||||
|
||||
ray.worker.cleanup()
|
||||
|
||||
@@ -146,7 +159,7 @@ class TaskStatusTest(unittest.TestCase):
|
||||
use_foo.remote()
|
||||
wait_for_errors(b"reinitialize_environment_variable", 1)
|
||||
# Check that the error message is in the task info.
|
||||
self.assertTrue(b"The reinitializer failed." in ray.error_info()[0][b"message"])
|
||||
self.assertIn(b"The reinitializer failed.", ray.error_info()[0][b"message"])
|
||||
|
||||
ray.worker.cleanup()
|
||||
|
||||
@@ -160,8 +173,8 @@ class TaskStatusTest(unittest.TestCase):
|
||||
wait_for_errors(b"function_to_run", 2)
|
||||
# Check that the error message is in the task info.
|
||||
self.assertEqual(len(ray.error_info()), 2)
|
||||
self.assertTrue(b"Function to run failed." in ray.error_info()[0][b"message"])
|
||||
self.assertTrue(b"Function to run failed." in ray.error_info()[1][b"message"])
|
||||
self.assertIn(b"Function to run failed.", ray.error_info()[0][b"message"])
|
||||
self.assertIn(b"Function to run failed.", ray.error_info()[1][b"message"])
|
||||
|
||||
ray.worker.cleanup()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user