def main(): redis.set("hits:homepage", 2000) redis.set("hits:loginpage", 75) homepage = redis.get("hits:homepage") loginpage = redis.get("hits:loginpage") # Register our script with the Redis Python client and # return a callable object for invoking our script. stats = redis.register_script(stats_script) # Invoke our "sum" script. # This calls SCRIPT LOAD and then stores # the SHA1 digest of the script for future use. total = stats(["hits:homepage", "hits:loginpage"], ["sum"]) assert (total == 2075) # Two more tests. max = stats(["hits:homepage", "hits:loginpage"], ["max"]) assert (max == 2000) print('calling script to sum {} + {} = {}'.format(homepage, loginpage, total)) print('calling script get max {} or {} ? {}'.format( homepage, loginpage, max))
def release_lock_lua(redis, lockname, identifier): lua = redis.register_script(""" if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) or true end """) return lua(keys=[lockname], args=[identifier])
def acquire_lock_with_timeout_lua(redis, lockname, lock_timeout, identifier): lua = redis.register_script(""" if redis.call('exists', KEYS[1]) == 0 then return redis.call('setex', KEYS[1], unpack(ARGV)) end """) return lua(keys=[lockname], args=[lock_timeout, identifier])
def purchase_item_lua_script(redis, market, buyer, seller, inventory, item, itemid): lua = redis.register_script(""" local price = tonumber(redis.call('zscore', KEYS[1], ARGV[1])) local funds = tonumber(redis.call('hget', KEYS[2], 'funds')) if price and funds and funds >= price then redis.call('hincrby', KEYS[3], 'funds', price) redis.call('hincrby', KEYS[2], 'funds', -price) redis.call('sadd', KEYS[4], ARGV[2]) redis.call('zrem', KEYS[1], ARGV[1]) return ture end """) return lua(keys=[market, buyer, seller, inventory], args=[item, itemid])
def __init__(self, key, expires=60, timeout=10, redis=None): """Distributed locking using Redis Lua scripting for CAS operations. Usage:: with Lock('my_lock'): print "Critical section" :param expires: We consider any existing lock older than ``expires`` seconds to be invalid in order to detect crashed clients. This value must be higher than it takes the critical section to execute. :param timeout: If another client has already obtained the lock, sleep for a maximum of ``timeout`` seconds before giving up. A value of 0 means we never wait. :param redis: The redis instance to use if the default global redis connection is not desired. """ self.key = key self.timeout = timeout self.expires = expires if not redis: redis = global_connection.redis self.redis = redis self._acquire_lua = redis.register_script(acquire_lua) self._release_lua = redis.register_script(release_lua) self.lock_key = None
def count_prefix(prefix): redis = get_redis() if redis: text = """ local n = 0 for _,k in ipairs(redis.call('keys', ARGV[1])) do n = n + 1 end return n """ script = redis.register_script(text) pipe = redis.pipeline() script(args=[prefix], client=pipe) r = pipe.execute() return r[0] return 0
def acquire_semaphore(redis, semname, limit, timeout=10): semname = "semaphore:" + semname ident = str(uuid.uuid4()) now = time.time() # 清除所有已过期信号量 # 如果还有剩余的信号量可用,那么获取信号量 lua = redis.register_script(""" redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', ARGV[1]) if redis.call('ZCARD', KEYS[1]) < tonumber(ARGV[2]) then redis.call('zadd', KEYS[1], ARGV[3], ARGV[4]) return ARGV[4] end """) return lua(keys=[semname], args=[now-timeout, limit, now, ident])
def __init__(self, redis, name, prefix="gevent-queue:lock", timeout=30, retry_wait=1): self.redis = redis self.lock_name = prefix + ":" + name self.threadlocal = threading.local() safe_release_lua = """ if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end """ self.safe_release = redis.register_script(safe_release_lua) self.timeout = timeout self.retry_wait = retry_wait
def purchase_item_lua(redis, buyerid, itemid, sellerid, lprice): buyer = "test:users:%s" % str(buyerid) seller = "test:users:%s" % str(sellerid) item = "%s.%s" % (str(itemid), str(sellerid)) inventory = "test:inventory:%s" % str(buyerid) lua = redis.register_script(""" -- 获取商品的价格以及买家可用的RMB local price = tonumber(redis.call('zscore', KEYS[1], ARGV[1])) local funds = tonumber(redis.call('hget', KEYS[2], 'funds')) if price and funds and funds >= price then -- 如果商品仍在销售并且买家也有足够的钱,那么对商品和前进行相应的转移。 redis.call('hincrby', KEYS[3], 'funds', price) redis.call('hincrby', KEYS[2], 'funds', -price) redis.call('sadd', KEYS[4], ARGV[2]) redis.call('zrem', KEYS[1], ARGV[1]) return true end """) return lua(keys=["test:market:", buyer, seller, inventory], args=[item, itemid]) return purchase_item_lua_script(redis, "test:market:", buyer, seller, inventory, item, itemid)
def mbrpoplpush(lists, deslist, timeout=0): redis = get_redis() if redis: text = """ local ret for i, k in pairs(KEYS) do ret = redis.call('rpoplpush', k, ARGV[1]) if ret then return {k, ret} end end """ script = redis.register_script(text) end = time.time() + timeout while 1: r = script(keys=lists, args=[deslist], client=redis) if r: return r if time.time() < end: time.sleep(.001) else: break
verify_script = ''' local source = KEYS[1] local source_embedding = redis.call("lrange", "embedding:"..source, 0, -1) local distance = 0 for i = 1, #source_embedding do distance = distance + (source_embedding[i] - KEYS[1+i])^2 end distance = math.sqrt(distance) return {"euclidean_distance", tostring(distance)} ''' command = redis.register_script(verify_script) #---------------------------- float(command(keys = ["angelina", *target_embedding])[1].decode()) <= 10 #---------------------------- #server side recognition find_script = ''' local db = redis.call("SCAN", 0, "MATCH", "embedding:*")[2] local identities = {} local distances = {} local idx = 1
def __init__(self, redis, prefix): self._prefix = prefix self._r = redis self._add_script = redis.register_script(Collection.add_lua)