Example #1
0
    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()
Example #2
0
    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
Example #3
0
    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)