Change get to take a timeout and multiple object IDs. (#212)

* Change plasma_get to take a timeout and an array of object IDs.

* Address comments.

* Bug fix related to computing object hashes.

* Add test.

* Fix file descriptor leak.

* Fix valgrind.

* Formatting.

* Remove call to plasma_contains from the plasma client. Use timeout internally in ray.get.

* small fixes
This commit is contained in:
Robert Nishihara
2017-01-19 12:21:12 -08:00
committed by Philipp Moritz
parent 4f6100b67f
commit b98a63fd3a
16 changed files with 715 additions and 1016 deletions
+29 -20
View File
@@ -428,20 +428,29 @@ class Worker(object):
# Optionally do something with the contained_objectids here.
contained_objectids = []
def get_object(self, objectid):
"""Get the value in the local object store associated with objectid.
def get_object(self, object_ids):
"""Get the value or values in the local object store associated with object_ids.
Return the value from the local object store for objectid. This will block
until the value for objectid has been written to the local object store.
Return the values from the local object store for object_ids. This will block
until all the values for object_ids have been written to the local object store.
Args:
objectid (object_id.ObjectID): The object ID of the value to retrieve.
object_ids (List[object_id.ObjectID]): A list of the object IDs whose
values should be retrieved.
"""
self.plasma_client.fetch([objectid.id()])
deserialized = numbuf.retrieve_list(objectid.id(), self.plasma_client.conn)
self.plasma_client.fetch([object_id.id() for object_id in object_ids])
# We currently pass in a timeout of one second.
unready_ids = object_ids
while len(unready_ids) > 0:
results = numbuf.retrieve_list([object_id.id() for object_id in object_ids], self.plasma_client.conn, 1000)
unready_ids = [object_id for (object_id, val) in results if val is None]
# This would be a natural place to issue a command to reconstruct some of
# the objects.
# Unwrap the object from the list (it was wrapped put_object).
assert len(deserialized) == 1
return deserialized[0]
assert len(results) == len(object_ids)
for i in range(len(results)):
assert results[i][0] == object_ids[i].id()
return [result[1][0] for result in results]
def submit_task(self, function_id, func_name, args):
"""Submit a remote task to the scheduler.
@@ -1228,17 +1237,17 @@ def flush_log(worker=global_worker):
worker.photon_client.log_event(event_log_key, event_log_value)
worker.events = []
def get(objectid, worker=global_worker):
def get(object_ids, worker=global_worker):
"""Get a remote object or a list of remote objects from the object store.
This method blocks until the object corresponding to objectid is available in
This method blocks until the object corresponding to the object ID is available in
the local object store. If this object is not in the local object store, it
will be shipped from an object store that has it (once the object has been
created). If objectid is a list, then the objects corresponding to each object
created). If object_ids is a list, then the objects corresponding to each object
in the list will be returned.
Args:
objectid: Object ID of the object to get or a list of object IDs to get.
object_ids: Object ID of the object to get or a list of object IDs to get.
Returns:
A Python object or a list of Python objects.
@@ -1249,19 +1258,19 @@ def get(objectid, worker=global_worker):
if worker.mode == PYTHON_MODE:
# In PYTHON_MODE, ray.get is the identity operation (the input will actually be a value not an objectid)
return objectid
if isinstance(objectid, list):
values = [worker.get_object(x) for x in objectid]
return object_ids
if isinstance(object_ids, list):
values = worker.get_object(object_ids)
for i, value in enumerate(values):
if isinstance(value, RayTaskError):
raise RayGetError(objectid[i], value)
raise RayGetError(object_ids[i], value)
return values
else:
value = worker.get_object(objectid)
value = worker.get_object([object_ids])[0]
if isinstance(value, RayTaskError):
# If the result is a RayTaskError, then the task that created this object
# failed, and we should propagate the error message here.
raise RayGetError(objectid, value)
raise RayGetError(object_ids, value)
return value
def put(value, worker=global_worker):
@@ -1705,7 +1714,7 @@ def get_arguments_for_execution(function, serialized_args, worker=global_worker)
for (i, arg) in enumerate(serialized_args):
if isinstance(arg, photon.ObjectID):
# get the object from the local object store
argument = worker.get_object(arg)
argument = worker.get_object([arg])[0]
if isinstance(argument, RayTaskError):
# If the result is a RayTaskError, then the task that created this
# object failed, and we should propagate the error message here.