Spaces:
Running
Running
import json | |
import redis | |
import uuid | |
class RedisLock: | |
def __init__(self, redis_url, lock_name, timeout_secs): | |
self.lock_name = lock_name | |
self.lock_id = str(uuid.uuid4()) | |
self.timeout_secs = timeout_secs | |
self.lock_obtained = False | |
self.redis = redis.Redis.from_url(redis_url, decode_responses=True) | |
def aquire_lock(self): | |
# nx=True will only set this key if it _hasn't_ already been set | |
self.lock_obtained = self.redis.set( | |
self.lock_name, self.lock_id, nx=True, ex=self.timeout_secs | |
) | |
return self.lock_obtained | |
def renew_lock(self): | |
# xx=True will only set this key if it _has_ already been set | |
return self.redis.set( | |
self.lock_name, self.lock_id, xx=True, ex=self.timeout_secs | |
) | |
def release_lock(self): | |
lock_value = self.redis.get(self.lock_name) | |
if lock_value and lock_value.decode("utf-8") == self.lock_id: | |
self.redis.delete(self.lock_name) | |
class RedisDict: | |
def __init__(self, name, redis_url): | |
self.name = name | |
self.redis = redis.Redis.from_url(redis_url, decode_responses=True) | |
def __setitem__(self, key, value): | |
serialized_value = json.dumps(value) | |
self.redis.hset(self.name, key, serialized_value) | |
def __getitem__(self, key): | |
value = self.redis.hget(self.name, key) | |
if value is None: | |
raise KeyError(key) | |
return json.loads(value) | |
def __delitem__(self, key): | |
result = self.redis.hdel(self.name, key) | |
if result == 0: | |
raise KeyError(key) | |
def __contains__(self, key): | |
return self.redis.hexists(self.name, key) | |
def __len__(self): | |
return self.redis.hlen(self.name) | |
def keys(self): | |
return self.redis.hkeys(self.name) | |
def values(self): | |
return [json.loads(v) for v in self.redis.hvals(self.name)] | |
def items(self): | |
return [(k, json.loads(v)) for k, v in self.redis.hgetall(self.name).items()] | |
def get(self, key, default=None): | |
try: | |
return self[key] | |
except KeyError: | |
return default | |
def clear(self): | |
self.redis.delete(self.name) | |
def update(self, other=None, **kwargs): | |
if other is not None: | |
for k, v in other.items() if hasattr(other, "items") else other: | |
self[k] = v | |
for k, v in kwargs.items(): | |
self[k] = v | |
def setdefault(self, key, default=None): | |
if key not in self: | |
self[key] = default | |
return self[key] | |