Beispiel #1
0
    async def fetch_cluster_info(self):
        logger.info('Loading cluster info from {}...'.format(self._nodes))
        tasks = [
            asyncio.ensure_future(
                self._get_raw_cluster_info_from_node(node), loop=self._loop
            ) for node in self._nodes
        ]
        try:
            for task in asyncio.as_completed(tasks, loop=self._loop):
                try:
                    nodes_raw_response = await task
                    self._cluster_manager = ClusterNodesManager.create(
                        nodes_raw_response)
                    logger.info('Cluster info loaded successfully: %s',
                                list(nodes_raw_response))
                    return
                except (ReplyError, ProtocolError,
                        ConnectionError, OSError) as exc:
                    logger.warning(
                        "Loading cluster info from a node failed with {}"
                        .format(repr(exc))
                    )
        finally:
            for task in tasks:
                task.cancel()
            # Wait until all tasks have closed their connection
            await asyncio.gather(
                *tasks, loop=self._loop, return_exceptions=True)

        raise RedisClusterError(
            "No cluster info could be loaded from any host")
Beispiel #2
0
async def create_pool_cluster(
        nodes, *, db=0, password=None, encoding=None,
        minsize=10, maxsize=10, commands_factory=Redis, loop=None):
    """
    Create Redis Pool Cluster.

    :param nodes = [(address1, port1), (address2, port2), ...]
    :param db - int
    :param password: str
    :param encoding: str
    :param minsize: int
    :param maxsize: int
    :param commands_factory: obj
    :param loop: obj
    :return RedisPoolCluster instance.
    """
    if not nodes or not isinstance(nodes, (tuple, list)):
        raise RedisClusterError(
            'Cluster nodes is not set properly. {0}'.
            format(create_pool_cluster.__doc__))

    cluster = RedisPoolCluster(
        nodes, db, password, encoding=encoding, minsize=minsize,
        maxsize=maxsize, commands_factory=commands_factory, loop=loop)
    await cluster.initialize()
    return cluster
Beispiel #3
0
 async def connect():
     try:
         return await create_pool_cluster(NODES, loop=loop, encoding='utf8')
     except RedisClusterError:
         raise RedisClusterError(
             "Could not connect to cluster. "
             "Did you start it with the setupcluster.py script?")
Beispiel #4
0
    async def cluster_del_slots(self, slot, *slots, many=False, slaves=False):
        """
        Set hash slots as unbound in the cluster.
        It determines by itself what node the slot is in and sends it there

        If many = True wil be applied to all master nodes, with slaves = True
        it will affect all nodes
        """

        if many:
            return await self._execute_nodes(
                'cluster_del_slots', slot, *slots, slaves=slaves
            )

        slots = set((slot,) + slots)
        if not all(isinstance(s, int) for s in slots):
            raise TypeError("All parameters must be of type int")

        max_slot = self._cluster_manager.REDIS_CLUSTER_HASH_SLOTS
        if not all(max_slot >= s >= 0 for s in slots):
            raise RedisClusterError('Wrong slot {}.'.format(slot))

        nodes = {}
        for slot in slots:
            node = self._cluster_manager.get_node_by_slot(slot)
            if not node:
                continue

            node_slots = nodes.setdefault(node.address, set())
            node_slots.add(slot)

        if not nodes:
            raise RedisClusterError(
                'Redis cluster don\'t know about these slot(s)'
            )

        if len(nodes) == 1:
            n_address, n_slots = nodes.popitem()
            return await self._execute_node(
                n_address, 'cluster_del_slots', *n_slots
            )

        return await asyncio.gather(*[
            self._execute_node(n_address, 'cluster_del_slots', *n_slots)
            for n_address, n_slots in nodes.items()
        ], loop=self._loop)
Beispiel #5
0
 def determine_slot(self, *keys):
     if any(key is None for key in keys):
         raise TypeError('key must not be None')
     if len(keys) == 1:
         return self.key_slot(keys[0])
     else:
         slots = {self.key_slot(key) for key in keys}
         if len(slots) != 1:
             raise RedisClusterError(
                 'all keys must map to the same key slot')
         return slots.pop()