Ejemplo n.º 1
0
    async def _execute_node(self, pool, command, *args, **kwargs):
        """Execute redis command and returns Future waiting for the answer.

        :param command str
        :param pool obj
        Raises:
        * TypeError if any of args can not be encoded as bytes.
        * ReplyError on redis '-ERR' responses.
        * ProtocolError when response can not be decoded meaning connection
          is broken.
        """
        cmd = decode(command, 'utf-8').lower()
        try:
            with await pool as conn:
                return await getattr(conn, cmd)(*args, **kwargs)
        except ReplyError as err:
            address = parse_moved_response_error(err)
            if address is None:
                raise

            logger.debug('Got MOVED command: {}'.format(err))
            self._moved_count += 1
            if self._moved_count >= self.MAX_MOVED_COUNT:
                await self.initialize()
                pool = self.get_node(command, *args, **kwargs)
                with await pool as conn:
                    return await getattr(conn, cmd)(*args, **kwargs)
            else:
                conn = await self.create_connection(address)
                res = await getattr(conn, cmd)(*args, **kwargs)
                conn.close()
                await conn.wait_closed()
                return res
Ejemplo n.º 2
0
    async def _execute_node(self, pool, command, *args, **kwargs):
        """Execute redis command and returns Future waiting for the answer.

        :param command str
        :param pool obj
        Raises:
        * TypeError if any of args can not be encoded as bytes.
        * ReplyError on redis '-ERR' responses.
        * ProtocolError when response can not be decoded meaning connection
          is broken.
        """
        cmd = decode(command, 'utf-8').lower()
        try:
            with await pool as conn:
                return await getattr(conn, cmd)(*args, **kwargs)
        except ReplyError as err:
            address = parse_moved_response_error(err)
            if address is None:
                raise

            logger.debug('Got MOVED command: {}'.format(err))
            self._moved_count += 1
            if self._moved_count >= self.MAX_MOVED_COUNT:
                await self.initialize()
                pool = self.get_node(command, *args, **kwargs)
                with await pool as conn:
                    return await getattr(conn, cmd)(*args, **kwargs)
            else:
                conn = await self.create_connection(address)
                res = await getattr(conn, cmd)(*args, **kwargs)
                conn.close()
                await conn.wait_closed()
                return res
Ejemplo n.º 3
0
 def _assign_slots(self, masters, addresses):
     slot_boundaries = [
         math.floor(i * REDIS_SLOT_COUNT / len(masters))
         for i in range(len(masters) + 1)
     ]
     slot_ranges = [
         range(b1, b2)
         for b1, b2 in zip(slot_boundaries, slot_boundaries[1:])
     ]
     for master, slot_range, address in zip(masters, slot_ranges,
                                            addresses):
         logger.debug("Assigning master at {} slots {}-{}".format(
             address, slot_range.start, slot_range.stop - 1))
         slots = ' '.join(str(slot) for slot in slot_range)
         try:
             self._send_command_and_expect_ok(
                 master, 'CLUSTER ADDSLOTS {}\r\n'.format(slots))
         except IOError as e:
             raise IOError(
                 "ADDSLOTS failed. Maybe a cluster is already running? "
                 "({}).".format(str(e)))
Ejemplo n.º 4
0
 def _determine_node_id(self, socket, address):
     socket.sendall(b'CLUSTER NODES\r\n')
     data = self._read_bulk_string_response(socket)
     node_id = data[:40].decode('utf-8')
     logger.debug("Master at {} has node id {}.".format(address, node_id))
     return node_id