class RedisLock(Lock): def __init__(self, namespace='lock', **redis_kwargs): import redis from redis.sentinel import Sentinel redis_kwargs['decode_responses'] = True if redis_kwargs.get('sentinel') and redis_kwargs.get('sentinel_service'): sentinels = [tuple(l.split(':')) for l in redis_kwargs.pop('sentinel').split(',')] sentinel_service = redis_kwargs.pop('sentinel_service') kwargs = {k: v for k, v in redis_kwargs.items() if k in ["decode_responses", "password", "db", "socket_timeout"]} self._redis = Sentinel(sentinels, **kwargs).master_for(sentinel_service) else: kwargs = {k: v for k, v in redis_kwargs.items() if "sentinel" not in k} self._redis = redis.Redis(**kwargs) self._redis.ping() self._namespace = namespace info("Created redis lock manager with socket_timeout of {}s".format(redis_kwargs['socket_timeout'])) def __key(self, name): return "{}:{}".format(self._namespace, name) def lock(self, name, owner, expiration=1, allow_owner_relock=False): """ Obtain the named lock. :param allow_owner_relock: bool :param name: str the name of the lock :param owner: str a unique name for the locking node :param expiration: int in seconds, 0 expiration means forever """ import redis try: if int(expiration) < 1: expiration = 1 key = self.__key(name) non_existing = not (allow_owner_relock and self._redis.get(key) == owner) return self._redis.set(key, owner, ex=int(expiration), nx=non_existing) except redis.exceptions.ResponseError as e: exception("Unable to obtain lock, local state: name: %s, owner: %s, expiration: %s, allow_owner_relock: %s", name, owner, expiration, allow_owner_relock) def unlock(self, name, owner): """ Release the named lock. :param name: str the name of the lock :param owner: str a unique name for the locking node """ key = self.__key(name) if self._redis.get(key) == owner: self._redis.delete(key) return True return False def check_lock(self, name): return self._redis.get(self.__key(name)) is not None def print_locks(self): keys = self._redis.keys(self.__key('*')) for key in keys: print("{} locked by {}, expires in {} seconds".format(key, self._redis.get(key), self._redis.ttl(key)))
def __init__(self, servers, hash_method='crc32', sentinel=None, strict_redis=False): self.nodes = [] self.connections = {} self.pool = None servers = format_servers(servers) if sentinel: sentinel = Sentinel(sentinel['hosts'], socket_timeout=sentinel.get( 'socket_timeout', 1)) for server_config in servers: name = server_config.pop('name') server_config["max_connections"] = int( server_config.get("max_connections", 100)) if name in self.connections: raise ValueError("server's name config must be unique") if sentinel: self.connections[name] = SentinelRedis(sentinel, name) elif strict_redis: self.connections[name] = redis.StrictRedis(**server_config) else: self.connections[name] = redis.Redis(**server_config) server_config['name'] = name self.nodes.append(name) self.ring = HashRing(self.nodes, hash_method=hash_method)
def __init__(self, servers, hash_method='crc32', sentinel=None): self.nodes = [] self.connections = {} self.pool = None servers = format_servers(servers) if sentinel: sentinel = Sentinel(sentinel['hosts'], socket_timeout=sentinel.get('socket_timeout', 1)) for server_config in servers: name = server_config.pop('name') if name in self.connections: raise ValueError("server's name config must be unique") if sentinel: self.connections[name] = SentinelRedis(sentinel, name) else: self.connections[name] = redis.Redis(**server_config) server_config['name'] = name self.nodes.append(name) self.ring = HashRing(self.nodes, hash_method=hash_method)