def write(self, data: bytes): expected_length = self.get_length() if not expected_length: raise IOError("unknown blob length") if self.buffer is None: log.warning("writer has already been closed") if not self.finished.done(): self.finished.cancel() return raise IOError('I/O operation on closed file') self._hashsum.update(data) self.len_so_far += len(data) if self.len_so_far > expected_length: self.finished.set_exception( InvalidDataError( f'Length so far is greater than the expected length. {self.len_so_far} to {expected_length}' )) self.close_handle() return self.buffer.write(data) if self.len_so_far == expected_length: blob_hash = self.calculate_blob_hash() if blob_hash != self.expected_blob_hash: self.finished.set_exception( InvalidBlobHashError( f"blob hash is {blob_hash} vs expected {self.expected_blob_hash}" )) elif self.finished and not (self.finished.done() or self.finished.cancelled()): self.finished.set_result(self.buffer.getvalue()) self.close_handle()
def __init__(self, loop: asyncio.BaseEventLoop, blob_dir: str, blob_hash: str, length: typing.Optional[int] = None, blob_completed_callback: typing.Optional[typing.Callable[ ['BlobFile'], typing.Awaitable]] = None): if not is_valid_blobhash(blob_hash): raise InvalidBlobHashError(blob_hash) self.loop = loop self.blob_hash = blob_hash self.length = length self.blob_dir = blob_dir self.file_path = os.path.join(blob_dir, self.blob_hash) self.writers: typing.List[HashBlobWriter] = [] self.verified: asyncio.Event = asyncio.Event(loop=self.loop) self.finished_writing = asyncio.Event(loop=loop) self.blob_write_lock = asyncio.Lock(loop=loop) if self.file_exists: length = int(os.stat(os.path.join(blob_dir, blob_hash)).st_size) self.length = length self.verified.set() self.finished_writing.set() self.saved_verified_blob = False self.blob_completed_callback = blob_completed_callback
def __init__(self, loop: asyncio.BaseEventLoop, blob_hash: str, length: typing.Optional[int] = None, blob_completed_callback: typing.Optional[typing.Callable[ ['AbstractBlob'], asyncio.Task]] = None, blob_directory: typing.Optional[str] = None): self.loop = loop self.blob_hash = blob_hash self.length = length self.blob_completed_callback = blob_completed_callback self.blob_directory = blob_directory self.writers: typing.Dict[typing.Tuple[typing.Optional[str], typing.Optional[int]], HashBlobWriter] = {} self.verified: asyncio.Event = asyncio.Event(loop=self.loop) self.writing: asyncio.Event = asyncio.Event(loop=self.loop) self.readers: typing.List[typing.BinaryIO] = [] if not is_valid_blobhash(blob_hash): raise InvalidBlobHashError(blob_hash)