def _deserialize_object(self, data, metadata, object_id): if metadata: if metadata == ray_constants.PICKLE5_BUFFER_METADATA: if not self.use_pickle: raise ValueError("Receiving pickle5 serialized objects " "while the serialization context is " "using pyarrow as the backend.") try: in_band, buffers = unpack_pickle5_buffers(data) if len(buffers) > 0: obj = pickle.loads(in_band, buffers=buffers) else: obj = pickle.loads(in_band) # cloudpickle does not provide error types except pickle.pickle.PicklingError: raise DeserializationError() # Check that there are no ObjectIDs serialized in arguments # that are inlined. if object_id.is_nil(): assert len(self.get_and_clear_contained_object_ids()) == 0 else: worker = ray.worker.global_worker worker.core_worker.add_contained_object_ids( object_id, self.get_and_clear_contained_object_ids(), ) return obj # Check if the object should be returned as raw bytes. if metadata == ray_constants.RAW_BUFFER_METADATA: if data is None: return b"" return data.to_pybytes() # Otherwise, return an exception object based on # the error type. error_type = int(metadata) if error_type == ErrorType.Value("WORKER_DIED"): return RayWorkerError() elif error_type == ErrorType.Value("ACTOR_DIED"): return RayActorError() elif error_type == ErrorType.Value("OBJECT_UNRECONSTRUCTABLE"): return UnreconstructableError(ray.ObjectID(object_id.binary())) else: assert error_type != ErrorType.Value("OBJECT_IN_PLASMA"), \ "Tried to get object that has been promoted to plasma." assert False, "Unrecognized error type " + str(error_type) elif data: raise ValueError("non-null object should always have metadata") else: # Object isn't available in plasma. This should never be returned # to the user. We should only reach this line if this object was # deserialized as part of a list, and another object in the list # throws an exception. return plasma.ObjectNotAvailable
def _deserialize_object_from_arrow(self, data, metadata, object_id): if metadata: if metadata == ray_constants.PICKLE5_BUFFER_METADATA: if not self.use_pickle: raise ValueError("Receiving pickle5 serialized objects " "while the serialization context is " "using pyarrow as the backend.") try: in_band, buffers = unpack_pickle5_buffers(data) if len(buffers) > 0: return pickle.loads(in_band, buffers=buffers) else: return pickle.loads(in_band) # cloudpickle does not provide error types except pickle.pickle.PicklingError: raise DeserializationError() # Check if the object should be returned as raw bytes. if metadata == ray_constants.RAW_BUFFER_METADATA: if data is None: return b"" return data.to_pybytes() # Otherwise, return an exception object based on # the error type. error_type = int(metadata) if error_type == ErrorType.Value("WORKER_DIED"): return RayWorkerError() elif error_type == ErrorType.Value("ACTOR_DIED"): return RayActorError() elif error_type == ErrorType.Value("OBJECT_UNRECONSTRUCTABLE"): return UnreconstructableError(ray.ObjectID(object_id.binary())) else: assert error_type != ErrorType.Value("OBJECT_IN_PLASMA"), \ "Tried to get object that has been promoted to plasma." assert False, "Unrecognized error type " + str(error_type) elif data: if self.use_pickle: raise ValueError("Receiving plasma serialized objects " "while the serialization context is " "using pickle5 as the backend.") try: # If data is not empty, deserialize the object. return pyarrow.deserialize(data, self.pyarrow_context) except pyarrow.DeserializationCallbackError: raise DeserializationError() else: # Object isn't available in plasma. This should never be returned # to the user. We should only reach this line if this object was # deserialized as part of a list, and another object in the list # throws an exception. return plasma.ObjectNotAvailable
def _serialize_to_msgpack(self, value): # Only RayTaskError is possible to be serialized here. We don't # need to deal with other exception types here. if isinstance(value, RayTaskError): metadata = str( ErrorType.Value("TASK_EXECUTION_EXCEPTION")).encode("ascii") value = value.to_bytes() else: metadata = ray_constants.OBJECT_METADATA_TYPE_CROSS_LANGUAGE python_objects = [] def _python_serializer(o): index = len(python_objects) python_objects.append(o) return index msgpack_data = MessagePackSerializer.dumps(value, _python_serializer) if python_objects: metadata = ray_constants.OBJECT_METADATA_TYPE_PYTHON pickle5_serialized_object = \ self._serialize_to_pickle5(metadata, python_objects) else: pickle5_serialized_object = None return MessagePackSerializedObject(metadata, msgpack_data, pickle5_serialized_object)
def serialize(self, value): """Serialize an object. Args: value: The value to serialize. """ if isinstance(value, bytes): # If the object is a byte array, skip serializing it and # use a special metadata to indicate it's raw binary. So # that this object can also be read by Java. return RawSerializedObject(value) else: # Only RayTaskError is possible to be serialized here. We don't # need to deal with other exception types here. if isinstance(value, RayTaskError): metadata = str(ErrorType.Value( "TASK_EXECUTION_EXCEPTION")).encode("ascii") else: metadata = ray_constants.PICKLE5_BUFFER_METADATA assert self.worker.use_pickle assert ray.cloudpickle.FAST_CLOUDPICKLE_USED writer = Pickle5Writer() # TODO(swang): Check that contained_object_ids is empty. inband = pickle.dumps(value, protocol=5, buffer_callback=writer.buffer_callback) return Pickle5SerializedObject( metadata, inband, writer, self.get_and_clear_contained_object_ids())
def _deserialize_object(self, data, metadata, object_id): if metadata: if metadata in [ ray_constants.OBJECT_METADATA_TYPE_CROSS_LANGUAGE, ray_constants.OBJECT_METADATA_TYPE_PYTHON ]: return self._deserialize_msgpack_data(data, metadata) # Check if the object should be returned as raw bytes. if metadata == ray_constants.OBJECT_METADATA_TYPE_RAW: if data is None: return b"" return data.to_pybytes() # Otherwise, return an exception object based on # the error type. try: error_type = int(metadata) except Exception: raise Exception( "Can't deserialize object: {}, metadata: {}".format( object_id, metadata)) # RayTaskError is serialized with pickle5 in the data field. # TODO (kfstorm): exception serialization should be language # independent. if error_type == ErrorType.Value("TASK_EXECUTION_EXCEPTION"): obj = self._deserialize_msgpack_data(data, metadata) assert isinstance(obj, RayTaskError) return obj elif error_type == ErrorType.Value("WORKER_DIED"): return RayWorkerError() elif error_type == ErrorType.Value("ACTOR_DIED"): return RayActorError() elif error_type == ErrorType.Value("OBJECT_UNRECONSTRUCTABLE"): return UnreconstructableError(ray.ObjectID(object_id.binary())) else: assert error_type != ErrorType.Value("OBJECT_IN_PLASMA"), \ "Tried to get object that has been promoted to plasma." assert False, "Unrecognized error type " + str(error_type) elif data: raise ValueError("non-null object should always have metadata") else: # Object isn't available in plasma. This should never be returned # to the user. We should only reach this line if this object was # deserialized as part of a list, and another object in the list # throws an exception. return PlasmaObjectNotAvailable
def _deserialize_object(self, data, metadata, object_ref): if metadata: metadata_fields = metadata.split(b",") if metadata_fields[0] in [ ray_constants.OBJECT_METADATA_TYPE_CROSS_LANGUAGE, ray_constants.OBJECT_METADATA_TYPE_PYTHON ]: return self._deserialize_msgpack_data(data, metadata_fields) # Check if the object should be returned as raw bytes. if metadata_fields[0] == ray_constants.OBJECT_METADATA_TYPE_RAW: if data is None: return b"" return data.to_pybytes() elif metadata_fields[ 0] == ray_constants.OBJECT_METADATA_TYPE_ACTOR_HANDLE: obj = self._deserialize_msgpack_data(data, metadata_fields) return _actor_handle_deserializer(obj) # Otherwise, return an exception object based on # the error type. try: error_type = int(metadata_fields[0]) except Exception: raise Exception(f"Can't deserialize object: {object_ref}, " f"metadata: {metadata}") # RayTaskError is serialized with pickle5 in the data field. # TODO (kfstorm): exception serialization should be language # independent. if error_type == ErrorType.Value("TASK_EXECUTION_EXCEPTION"): obj = self._deserialize_msgpack_data(data, metadata_fields) return RayError.from_bytes(obj) elif error_type == ErrorType.Value("WORKER_DIED"): return WorkerCrashedError() elif error_type == ErrorType.Value("ACTOR_DIED"): if data: pb_bytes = self._deserialize_msgpack_data( data, metadata_fields) if pb_bytes: return RayError.from_bytes(pb_bytes) return RayActorError() elif error_type == ErrorType.Value("TASK_CANCELLED"): return TaskCancelledError() elif error_type == ErrorType.Value("OBJECT_UNRECONSTRUCTABLE"): return ObjectLostError(object_ref.hex()) elif error_type == ErrorType.Value("RUNTIME_ENV_SETUP_FAILED"): return RuntimeEnvSetupError() else: assert error_type != ErrorType.Value("OBJECT_IN_PLASMA"), \ "Tried to get object that has been promoted to plasma." assert False, "Unrecognized error type " + str(error_type) elif data: raise ValueError("non-null object should always have metadata") else: # Object isn't available in plasma. This should never be returned # to the user. We should only reach this line if this object was # deserialized as part of a list, and another object in the list # throws an exception. return PlasmaObjectNotAvailable
def serialize(self, value): """Serialize an object. Args: value: The value to serialize. """ if isinstance(value, bytes): # If the object is a byte array, skip serializing it and # use a special metadata to indicate it's raw binary. So # that this object can also be read by Java. return RawSerializedObject(value) else: # Only RayTaskError is possible to be serialized here. We don't # need to deal with other exception types here. if isinstance(value, RayTaskError): metadata = str(ErrorType.Value( "TASK_EXECUTION_EXCEPTION")).encode("ascii") else: metadata = ray_constants.OBJECT_METADATA_TYPE_PYTHON return self._serialize_to_msgpack(metadata, value)
def _serialize_to_msgpack(self, value): # Only RayTaskError is possible to be serialized here. We don't # need to deal with other exception types here. contained_object_refs = [] if isinstance(value, RayTaskError): metadata = str( ErrorType.Value("TASK_EXECUTION_EXCEPTION")).encode("ascii") value = value.to_bytes() elif isinstance(value, ray.actor.ActorHandle): # TODO(fyresone): ActorHandle should be serialized via the # custom type feature of cross-language. serialized, actor_handle_id = value._serialization_helper() contained_object_refs.append(actor_handle_id) # Update ref counting for the actor handle metadata = ray_constants.OBJECT_METADATA_TYPE_ACTOR_HANDLE value = serialized else: metadata = ray_constants.OBJECT_METADATA_TYPE_CROSS_LANGUAGE python_objects = [] def _python_serializer(o): index = len(python_objects) python_objects.append(o) return index msgpack_data = MessagePackSerializer.dumps(value, _python_serializer) if python_objects: metadata = ray_constants.OBJECT_METADATA_TYPE_PYTHON pickle5_serialized_object = \ self._serialize_to_pickle5(metadata, python_objects) else: pickle5_serialized_object = None return MessagePackSerializedObject(metadata, msgpack_data, contained_object_refs, pickle5_serialized_object)