def get_or_new_instance_from_db(self, object_id, retry): """ @postcondition: Get object from memory or database and WAIT in case we are still waiting for it to be persisted. @param object_id: ID of the object to get @param retry: indicates if we should retry and wait @param class_id: Can be none. Class ID of the object to get. In order to avoid looking for metadata. @return: the object """ """ Retry while object is not 'registered' (not talking about 'stored'!) IMPORTANT: This is different than waiting for an object to be stored If the object is not registered we still do not know the class id of the instance in which to load the bytes. Due to concurrency we should read bytes and deserialize and unlock. Therefore there is Two waiting loops. (can we do it better?, more locking?) """ self.logger.verbose( "Get or create new instance from SL with object id %s in Heap ", str(object_id)) obtained = False wait_time = 0 sleep_time = Configuration.SLEEP_WAIT_REGISTERED / 1000 instance = None while not obtained: self.runtime.lock(object_id) try: instance = self.runtime.get_from_heap(object_id) if instance is None: obj_bytes = self.runtime.get_from_sl(object_id) msg = DeserializationLibUtilsSingleton.deserialize_grpc_message_from_db( obj_bytes) metadata = get_metadata(msg.metadata) instance_class_id = metadata.tags_to_class_ids[0] instance = self.new_instance(instance_class_id, object_id) instance.initialize_object_as_persistent() DeserializationLibUtilsSingleton.deserialize_object_from_db_bytes_aux( instance, metadata, msg.data, self.runtime) instance.set_hint(self.runtime.get_hint()) self.logger.debug("Object %s deserialized", object_id) if not instance.is_loaded(): self._get_from_db_and_fill(instance) obtained = True except: self.logger.debug("Received error while retrieving object %s", object_id, exc_info=True) if not retry or wait_time > Configuration.TIMEOUT_WAIT_REGISTERED: raise wait_time = wait_time + sleep_time self.logger.debug( "Object %s not found in DB. Waiting and retry...", object_id) time.sleep(sleep_time) finally: self.runtime.unlock(object_id) return instance
def deserialize_metadata_from_db(self, obj_bytes_from_db): """ @postcondition: deserialize metadata from db (just metadata) @param obj_bytes_from_db: object bytes from db @return metadata of the object """ msg = common_messages.PersistentObjectInDB() msg.ParseFromString(obj_bytes_from_db) metadata = get_metadata(msg.metadata) return metadata
def deserialize_object_from_db(self, object_to_fill, object_bytes, runtime): """ @postcondition: Deserialize object from bytes @param object_to_fill: object to fill @param object_bytes: Object bytes @param runtime: runtime """ msg = self.deserialize_grpc_message_from_db(object_bytes) metadata = get_metadata(msg.metadata) self.deserialize_object_from_db_bytes_aux(object_to_fill, metadata, msg.data, runtime)
def serialize_for_db(self, object_id, metadata, object_bytes, is_store): """ @postcondition: serialize object for DB store or update @param object_id: id of the object to store or update @param object_bytes: object bytes @param is_store: indicates if it is for a store in DB @return serialized msg """ msg = common_messages.PersistentObjectInDB( data=object_bytes, metadata=get_metadata(metadata)) msgstr = msg.SerializeToString() return msgstr
def deserialize_objbytes_from_db_into_obj_data(self, object_id, obj_bytes_from_db, runtime): """ @postcondition: Deserialize object from bytes into ObjectData and return it. @param object_id: ID of object @param obj_bytes_from_db: Object bytes @param runtime: Runtime to use @return object data (to send) of this object """ logger.debug("OBJECT_ID %s, OBJ_BYTES %s", object_id, obj_bytes_from_db) msg = self.deserialize_grpc_message_from_db(obj_bytes_from_db) metadata = get_metadata(msg.metadata) obj_bytes = BytesIO(msg.data) logger.debug("METADATA %s and METADATA CLASS_ID %s", metadata, metadata[1][0]) return object_id, metadata[1][0], metadata, obj_bytes