Обработка буфера recv сокета Python - PullRequest
0 голосов
/ 07 апреля 2019

Я пытаюсь ускорить обработку сокетов в python, используя буфер / очередь ниже реализации для циклического буфера, которую я использую, чтобы прочитать максимальный размер из сокета localhost, используемого для IPC

class BufferHandling:
def __init__(self, buffer_size, max_chunk_size):
    self._read_index = 0
    self._write_index = 0

    self._buffer = bytearray(buffer_size)
    self._mem_view = memoryview(self._buffer)
    self._max_size = max_chunk_size

def fill_from_socket(self, _socket):
    logging.debug("2 fill: write index %s , read_index %s", self._write_index , self._read_index)
    if self._read_index > self._write_index:
        if self._read_index - self._write_index < self._max_size:
            raise RuntimeError("no place to write in buffer")

        ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
        self._write_index += ret
        #logging.debug("1 recv_from return with %s, write index %s", ret, self._write_index)
        return

    # write >= read
    _1st_write_size = len(self._mem_view) - self._write_index
    _2nd_write_size = self._read_index

    if _1st_write_size + _2nd_write_size < self._max_size:
        raise RuntimeError("no place to write in buffer")

    if _1st_write_size >= self._max_size:
        ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
        self._write_index += ret
        #logging.debug("2 recv_from return with %s , write index %s", ret, self._write_index)
        return

    # clear some room ...

    self._mem_view[:self._write_index - self._read_index] = self._mem_view[self._read_index: self._write_index]
    self._write_index = self._write_index - self._read_index
    self._read_index = 0
    ret = _socket.recv_into(self._mem_view[self._write_index:], self._max_size)
    self._write_index += ret
    logging.debug("3 recv_from return with %s, write index %s", ret, self._write_index)

"""
# read data from cyclic buffer
# if data found , return data according to _to_read size
# else return empty string
"""
def read_from_buffer(self, _to_read):
    logging.debug("1 write_index %s , read_index %s , _to_read %s", self._write_index, self._read_index, _to_read)
    if self._read_index > self._write_index:
        _1st_read_size = len(self._mem_view) - self._read_index
        _2nd_read_size = self._write_index

        if _1st_read_size >= _to_read:
            data = self._buffer[self._read_index: self._read_index + _to_read]
            self._read_index += _to_read

        else:
            data = self._buffer[self._read_index:] + self._buffer[:_to_read - _1st_read_size]
            self._read_index = _to_read - _1st_read_size
    else: # write >= read
        _read_less = min(_to_read, self._write_index - self._read_index)

        # if self._write_index - self._read_index < _to_read:
        #   logging.debug("2 write_index %s , read_index %s , _to_read %s", self._write_index,self._read_index,_to_read)
        #   #return None

        logging.debug("2 write_index %s , read_index %s , _to_read %s, _read %s", self._write_index, self._read_index, _to_read, _read_less)

        data = self._buffer[self._read_index: self._read_index + _read_less]
        self._read_index += _read_less

    return data

Я использую его следующим образом:

        self.__buffer = BufferHandling(self.__LOCALHOST_SOCKET_BUFFER_LEN * 4, 
self.__LOCALHOST_SOCKET_BUFFER_LEN)
data = self.__buffer.read_from_buffer(_to_read)
        if len(data) < _to_read:
            self._selector.select(rlist = [self.__connection], elist = [self.__connection])
            self.__buffer.fill_from_socket(self.__connection)
            data += self.__buffer.read_from_buffer(_to_read)

После того, как я столкнулся со многими проблемами, у меня возник вопрос: есть ли более Pythonic способ получить такой же эффект?или, может быть, предложить более «чистый» способ получить какую-то форму io buffering

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...