Ejemplo n.º 1
0
    def bulk_start(self, bulk_size=5000, keep_results=True):
        u""" Enable bulk mode

        Put the client into bulk mode. Instead of executing a command & waiting for
        the reply, all commands are send to Redis without fetching the result.
        The results get fetched whenever $bulk_size commands have been executed,
        which will also resets the counter, or of bulk_stop() is called.

        :param bulk_size:
            Number of commands to execute, before fetching results.
        :type bulk_size: int

        :param keep_results:
            If True, keep the results. The Results will be returned when calling bulk_stop.
        :type keep_results: bool

        :return: None
        """
        if self.bulk:
            raise PyRedisError(u"Already in bulk mode")
        self._bulk = True
        self._bulk_size = bulk_size
        self._bulk_size_current = 0
        if keep_results:
            self._bulk_results = []
            self._bulk_keep = True
Ejemplo n.º 2
0
 def __init__(self,
              seeds=None,
              database=0,
              password=None,
              encoding=None,
              slave_ok=False,
              conn_timeout=2,
              read_timeout=2,
              cluster_map=None):
     super(ClusterClient, self).__init__()
     if not bool(seeds) != bool(cluster_map):
         raise PyRedisError(
             u'Ether seeds or cluster_map has to be provided')
     self._cluster = True
     self._conns = dict()
     self._conn_timeout = conn_timeout
     self._read_timeout = read_timeout
     self._encoding = encoding
     self._password = password
     self._database = database
     self._slave_ok = slave_ok
     if cluster_map:
         self._map = cluster_map
     else:
         self._map = ClusterMap(seeds=seeds)
     self._map_id = self._map.id
Ejemplo n.º 3
0
    def execute(self, *args, shard_key=None, sock=None):
        """ Execute arbitrary redis command.

        :param args:
        :type args: list, int, float

        :param shard_key: (optional)
            Should be set to the key name you try to work with.
            Can not be used if sock is set.
        :type shard_key: string

        :param sock: (optional)
            The string representation of a socket, the command should be executed against.
            For example: "testhost_6379"
            Can not be used if shard_key is set.
        :type sock: string

        :return: result, exception
        """
        if not bool(shard_key) != bool(sock):
            raise PyRedisError('Ether shard_key or sock has to be provided')
        if not sock:
            sock = self._map[slot_from_key(shard_key)]
        conn = self._conns[sock]
        try:
            if not self._bulk:
                return self._execute_basic(conn=conn, *args)
            else:
                self._execute_bulk(conn=conn, *args)
        except PyRedisConnError as err:
            self.close()
            raise err
Ejemplo n.º 4
0
 def _fetch_map(self):
     for seed in self._seeds:
         conn = Connection(host=seed[0], port=seed[1], encoding='utf-8', password=self._password)
         try:
             conn.write(b'CLUSTER', b'SLOTS')
             return conn.read()
         except PyRedisError:
             pass
         finally:
             conn.close()
     raise PyRedisError('Could not get cluster info from any seed node: {0}'.format(self._seeds))
Ejemplo n.º 5
0
    def bulk_stop(self):
        u""" Stop bulk mode.

        All outstanding results from previous commands get fetched.
        If bulk_start was called with keep_results=True, return a list with all
        results from the executed commands in order. The list of results can also contain
        Exceptions, hat you should check for.

        :return: None, list
        """
        if not self.bulk:
            raise PyRedisError(u"Not in bulk mode")
        self._bulk_fetch()
        results = self._bulk_results
        self._bulk = False
        self._bulk_keep = False
        self._bulk_results = None
        self._bulk_size = None
        self._bulk_size_current = None
        return results
Ejemplo n.º 6
0
    def execute(self, *args, **_3to2kwargs):
        if 'retries' in _3to2kwargs:
            retries = _3to2kwargs['retries']
            del _3to2kwargs['retries']
        else:
            retries = 3
        if 'asking' in _3to2kwargs:
            asking = _3to2kwargs['asking']
            del _3to2kwargs['asking']
        else:
            asking = False
        if 'sock' in _3to2kwargs:
            sock = _3to2kwargs['sock']
            del _3to2kwargs['sock']
        else:
            sock = None
        if 'shard_key' in _3to2kwargs:
            shard_key = _3to2kwargs['shard_key']
            del _3to2kwargs['shard_key']
        else:
            shard_key = None
        u""" Execute arbitrary redis command.

        :param args:
        :type args: list, int, float

        :param shard_key: (optional)
            Should be set to the key name you try to work with.
            Can not be used if sock is set.
        :type shard_key: string

        :param sock: (optional)
            The string representation of a socket, the command should be executed against.
            For example: "testhost_6379"
            Can not be used if shard_key is set.
        :type sock: string

        :return: result, exception
        """
        if not bool(shard_key) != bool(sock):
            raise PyRedisError(u'Ether shard_key or sock has to be provided')
        if not sock:
            sock = self._get_slot_info(shard_key)
        if sock not in self._conns.keys():
            self._connect(sock)
        try:
            if asking:
                self._conns[sock].write(u'ASKING', *args)
            else:
                self._conns[sock].write(*args)
            return self._conns[sock].read()
        except ReplyError, err:
            errstr = unicode(err)
            if retries <= 1 and (errstr.startswith(u'MOVED')
                                 or errstr.startswith(u'ASK')):
                raise PyRedisError(
                    u'Slot moved to often or wrong shard_key, giving up,')
            if errstr.startswith(u'MOVED'):
                if not shard_key:
                    raise ReplyError(
                        u'Explicitly set socket, but key does not belong to this redis: {0}'
                        .format(sock))
                self._map_id = self._map.update(self._map_id)
                self._cleanup_conns()
                return self.execute(*args,
                                    shard_key=shard_key,
                                    retries=retries - 1)
            elif errstr.startswith(u'ASK'):
                sock = errstr.split()[2].replace(u':', u'_')
                return self.execute(*args,
                                    sock=sock,
                                    retries=retries - 1,
                                    asking=True)
            else:
                raise err