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
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
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
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))
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
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