def test_empty_write_buffer(self): x = WriteBuffer() s = bytes(x) self.assertEquals(s, b"") c = x.pop_chunk(4096) self.assertEquals(c, b"") self.assertEquals(len(x), 0)
def test_protocol6(self): wb = WriteBuffer() wb.append(b"foobar") res = bytes(format_args_in_redis_protocol("SET", "key", wb)) self.assertEqual( res, b"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n" b"$6\r\nfoobar\r\n")
def _make_test_buffer(self): x = WriteBuffer() x.append(b"23") x.append(b"4") x.append(b"") x.append(b"56789") x.appendleft(b"1") return x
def __init__(self, read_callback, close_callback, host=tornadis.DEFAULT_HOST, port=tornadis.DEFAULT_PORT, unix_domain_socket=None, read_page_size=tornadis.DEFAULT_READ_PAGE_SIZE, write_page_size=tornadis.DEFAULT_WRITE_PAGE_SIZE, connect_timeout=tornadis.DEFAULT_CONNECT_TIMEOUT, tcp_nodelay=False, aggressive_write=False, read_timeout=tornadis.DEFAULT_READ_TIMEOUT, ioloop=None): """Constructor. Args: read_callback: callback called when there is something to read (private, do not use from Client constructor). close_callback: callback called when the connection is closed (private, do not use from Client constructor). host (string): the host name to connect to. port (int): the port to connect to. unix_domain_socket (string): path to a unix socket to connect to (if set, overrides host/port parameters). read_page_size (int): page size for reading. write_page_size (int): page size for writing. connect_timeout (int): timeout (in seconds) for connecting. tcp_nodelay (boolean): set TCP_NODELAY on socket. aggressive_write (boolean): try to minimize write latency over global throughput (default False). read_timeout (int): timeout (in seconds) to read something on the socket (if nothing is read during this time, the connection is closed) (default: 0 means no timeout) ioloop (IOLoop): the tornado ioloop to use. """ self.host = host self.port = port self.unix_domain_socket = unix_domain_socket self._state = ConnectionState() self._ioloop = ioloop or tornado.ioloop.IOLoop.instance() if int(tornado.version[0]) >= 5: cb = tornado.ioloop.PeriodicCallback(self._on_every_second, 1000) else: cb = tornado.ioloop.PeriodicCallback(self._on_every_second, 1000, self._ioloop) self.__periodic_callback = cb self._read_callback = read_callback self._close_callback = close_callback self.read_page_size = read_page_size self.write_page_size = write_page_size self.connect_timeout = connect_timeout self.read_timeout = read_timeout self.tcp_nodelay = tcp_nodelay self.aggressive_write = aggressive_write self._write_buffer = WriteBuffer() self._listened_events = 0 self._last_read = datetime.now()
def _pipelined_call(self, pipeline, callback): buf = WriteBuffer() replies = len(pipeline.pipelined_args) cb = functools.partial(self._reply_aggregator, callback, replies) for args in pipeline.pipelined_args: self.__callback_queue.append(cb) tmp_buf = format_args_in_redis_protocol(*args) buf.append(tmp_buf) self.__connection.write(buf)
def test_write_buffer3(self): b = WriteBuffer() b.append(b"x" * 10000) chunk = self._pop_chunk_as_str(b, 4000) self.assertEquals(len(chunk), 4000) chunk = self._pop_chunk_as_str(b, 4000) self.assertEquals(len(chunk), 4000) chunk = self._pop_chunk_as_str(b, 4000) self.assertEquals(len(chunk), 2000)
def format_args_in_redis_protocol(*args): """Formats arguments into redis protocol... This function makes and returns a string/buffer corresponding to given arguments formated with the redis protocol. integer, text, string or binary types are automatically converted (using utf8 if necessary). More informations about the protocol: http://redis.io/topics/protocol Args: *args: full redis command as variable length argument list Returns: binary string (arguments in redis protocol) Examples: >>> format_args_in_redis_protocol("HSET", "key", "field", "value") '*4\r\n$4\r\nHSET\r\n$3\r\nkey\r\n$5\r\nfield\r\n$5\r\nvalue\r\n' """ buf = WriteBuffer() l = "*%d\r\n" % len(args) # noqa: E741 if six.PY2: buf.append(l) else: # pragma: no cover buf.append(l.encode('utf-8')) for arg in args: if isinstance(arg, six.text_type): # it's a unicode string in Python2 or a standard (unicode) # string in Python3, let's encode it in utf-8 to get raw bytes arg = arg.encode('utf-8') elif isinstance(arg, six.string_types): # it's a basestring in Python2 => nothing to do pass elif isinstance(arg, six.binary_type): # pragma: no cover # it's a raw bytes string in Python3 => nothing to do pass elif isinstance(arg, six.integer_types): tmp = "%d" % arg if six.PY2: arg = tmp else: # pragma: no cover arg = tmp.encode('utf-8') elif isinstance(arg, WriteBuffer): # it's a WriteBuffer object => nothing to do pass else: raise Exception("don't know what to do with %s" % type(arg)) l = "$%d\r\n" % len(arg) # noqa: E741 if six.PY2: buf.append(l) else: # pragma: no cover buf.append(l.encode('utf-8')) buf.append(arg) buf.append(b"\r\n") return buf