71 lines
1.7 KiB
Python
71 lines
1.7 KiB
Python
|
#!/usr/bin/env python
|
||
|
# -*- coding: utf-8 -*-
|
||
|
"""
|
||
|
Developed by niphlod@gmail.com
|
||
|
License MIT/BSD/GPL
|
||
|
|
||
|
Serves as base to implement Redis connection object and various utils
|
||
|
for redis_cache, redis_session and redis_scheduler in the future
|
||
|
Should-could be overriden in case redis doesn't keep up (e.g. cluster support)
|
||
|
to ensure compatibility with another - similar - library
|
||
|
"""
|
||
|
|
||
|
import logging
|
||
|
from threading import Lock
|
||
|
import time
|
||
|
from gluon import current
|
||
|
|
||
|
logger = logging.getLogger("web2py.redis_utils")
|
||
|
|
||
|
try:
|
||
|
import redis
|
||
|
from redis.exceptions import WatchError as RWatchError
|
||
|
from redis.exceptions import ConnectionError as RConnectionError
|
||
|
except ImportError:
|
||
|
logger.error("Needs redis library to work")
|
||
|
raise RuntimeError('Needs redis library to work')
|
||
|
|
||
|
|
||
|
locker = Lock()
|
||
|
|
||
|
|
||
|
def RConn(*args, **vars):
|
||
|
"""
|
||
|
Istantiates a StrictRedis connection with parameters, at the first time
|
||
|
only
|
||
|
"""
|
||
|
locker.acquire()
|
||
|
try:
|
||
|
instance_name = 'redis_conn_' + current.request.application
|
||
|
if not hasattr(RConn, instance_name):
|
||
|
setattr(RConn, instance_name, redis.StrictRedis(*args, **vars))
|
||
|
return getattr(RConn, instance_name)
|
||
|
finally:
|
||
|
locker.release()
|
||
|
|
||
|
def acquire_lock(conn, lockname, identifier, ltime=10):
|
||
|
while True:
|
||
|
if conn.set(lockname, identifier, ex=ltime, nx=True):
|
||
|
return identifier
|
||
|
time.sleep(.01)
|
||
|
|
||
|
|
||
|
_LUA_RELEASE_LOCK = """
|
||
|
if redis.call("get", KEYS[1]) == ARGV[1]
|
||
|
then
|
||
|
return redis.call("del", KEYS[1])
|
||
|
else
|
||
|
return 0
|
||
|
end
|
||
|
"""
|
||
|
|
||
|
|
||
|
def release_lock(instance, lockname, identifier):
|
||
|
return instance._release_script(
|
||
|
keys=[lockname], args=[identifier])
|
||
|
|
||
|
|
||
|
def register_release_lock(conn):
|
||
|
rtn = conn.register_script(_LUA_RELEASE_LOCK)
|
||
|
return rtn
|