import uuid import time import redis from haipproxy.config.settings import ( REDIS_HOST, REDIS_PORT, REDIS_DB, REDIS_PASSWORD, LOCKER_PREFIX) def get_redis_conn(**kwargs): host = kwargs.get('host', REDIS_HOST) port = kwargs.get('port', REDIS_PORT) db = kwargs.get('db', REDIS_DB) password = kwargs.get('password', REDIS_PASSWORD) return redis.StrictRedis(host, port, db, password) def acquire_lock(conn, lock_name, acquire_timeout=10, lock_timeout=10): """inspired by the book 'redis in action' """ identifier = str(uuid.uuid4()) lock_name = LOCKER_PREFIX + lock_name end = time.time() + acquire_timeout while time.time() < end: if conn.set(lock_name, identifier, lock_timeout, nx=True): return identifier elif not conn.ttl(lock_name) or conn.ttl(lock_name) == -1: conn.expire(lock_name, lock_timeout) time.sleep(0.1) return False def release_lock(conn, lock_name, identifier): pipe = conn.pipeline(True) lock_name = LOCKER_PREFIX + lock_name while True: try: pipe.watch(lock_name) identifier_origin = pipe.get(lock_name).decode() if identifier_origin == identifier: pipe.multi() pipe.delete(lock_name) pipe.execute() return True pipe.unwatch() break except redis.exceptions.WatchError: pass return False