common/consumer_table_pops.lua (83 lines of code) (raw):
local rets = {}
-- pop Key, Value and OP together.
local popsize = ARGV[1] * 3
local keys = redis.call('LRANGE', KEYS[1], -popsize, -1)
redis.call('LTRIM', KEYS[1], 0, -popsize-1)
local n = table.getn(keys)
for i = n, 1, -3 do
local op = keys[i-2]
local value = keys[i-1]
local key = keys[i]
local dbop = op:sub(1,1)
op = op:sub(2)
local ret = {key, op}
local jj = cjson.decode(value)
local size = #jj
for idx=1,size,2 do
table.insert(ret, jj[idx])
table.insert(ret, jj[idx+1])
end
table.insert(rets, ret)
if ARGV[2] == "0" then
-- do nothing, we don't want to modify redis during pop
elseif op == 'bulkset' or op == 'bulkcreate' or op == 'bulkremove' then
-- key is "OBJECT_TYPE:num", extract object type from key
key = key:sub(1, string.find(key, ':') - 1)
local len = #ret
local st = 3 -- since 1 and 2 is key/op
while st <= len do
local field = ret[st]
-- keyname is ASIC_STATE : OBJECT_TYPE : OBJECT_ID
local keyname = KEYS[2] .. ':' .. key .. ':' .. field
if op == 'bulkremove' then
redis.call('DEL', keyname)
else
-- value can be multiple a=v|a=v|... we need to split using gmatch
local vars = ret[st+1]
for value in string.gmatch(vars,'([^|]+)') do
local attr = value:sub(1, string.find(value, '=') - 1)
local val = value.sub(value, string.find(value, '=') + 1)
redis.call('HSET', keyname, attr, val)
end
end
st = st + 2
end
elseif
op == 'set' or
op == 'SET' or
op == 'create' or
op == 'remove' or
op == 'DEL' then
-- put entries into REDIS hash only when operations are this types
-- in case of delete command, remove entries
local keyname = KEYS[2] .. ':' .. key
if key == '' then
keyname = KEYS[2]
end
if dbop == 'D' then
redis.call('DEL', keyname)
else
local st = 3
local len = #ret
while st <= len do
redis.call('HSET', keyname, ret[st], ret[st+1])
st = st + 2
end
end
elseif
op == 'flush' or
op == 'flushresponse' or
op == 'get' or
op == 'bulkget' or
op == 'getresponse' or
op == 'notify' or
op == 'get_stats' or
op == 'clear_stats' or
op == 'attribute_capability_query' or
op == 'attribute_capability_response' or
op == 'attr_enum_values_capability_query' or
op == 'attr_enum_values_capability_response' or
op == 'object_type_get_availability_query' or
op == 'object_type_get_availability_response' or
op == 'stats_capability_query' or
op == 'stats_capability_response' or
op == 'stats_st_capability_query' or
op == 'stats_st_capability_response' then
-- do not modify db entries when spotted those commands, they are used to
-- trigger actions or get data synchronously from database
-- also force to allow only those commands, so when new command will be
-- added it will force programmer to support this command also here in
-- right way
else
-- notify redis that this command is not supported and require handling
error("unsupported operation command: " .. op .. ", FIXME")
end
end
return rets