aboutsummaryrefslogtreecommitdiffstats
path: root/openresty-ext/src/assembly/resources/openresty/nginx/luaext/dao/redis_db.lua
diff options
context:
space:
mode:
Diffstat (limited to 'openresty-ext/src/assembly/resources/openresty/nginx/luaext/dao/redis_db.lua')
-rw-r--r--openresty-ext/src/assembly/resources/openresty/nginx/luaext/dao/redis_db.lua199
1 files changed, 199 insertions, 0 deletions
diff --git a/openresty-ext/src/assembly/resources/openresty/nginx/luaext/dao/redis_db.lua b/openresty-ext/src/assembly/resources/openresty/nginx/luaext/dao/redis_db.lua
new file mode 100644
index 0000000..d35cb8e
--- /dev/null
+++ b/openresty-ext/src/assembly/resources/openresty/nginx/luaext/dao/redis_db.lua
@@ -0,0 +1,199 @@
+--[[
+
+ Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+--]]
+
+-- the client for redis, include the connection pool management and api implements
+local redis = require('resty.redis')
+local tbl_util = require('lib.utils.table_util')
+
+local _M = {
+}
+_M._VERSION = '0.0.1'
+_M._DESCRIPTION = 'msb_redis_module'
+
+local mt = { __index = _M }
+
+local tbl_insert = table.insert
+local tbl_sort = table.sort
+local tbl_isempty = tbl_util.isempty
+
+function _M.new(self, conf)
+ self.host = conf.host
+ self.port = conf.port
+ self.timeout = conf.timeout
+ self.dbid = conf.dbid
+ self.poolsize = conf.poolsize
+ self.idletimeout = conf.idletimeout
+
+ local red = redis:new()
+ return setmetatable({redis = red}, mt)
+end
+
+function _M.connectdb(self)
+ local host = self.host
+ local port = self.port
+ local dbid = self.dbid
+ local red = self.redis
+
+ if not (host and port) then
+ return nil, 'no host:port avaliable provided'
+ end
+
+ --set default value
+ if not dbid then dbid = 0 end
+ local timeout = self.timeout
+ if not timeout then
+ timeout = 1000 -- 1s
+ end
+
+ red:set_timeout(timeout)
+
+ local ok, err
+ if host and port then
+ ok, err = red:connect(host, port)
+ if ok then return red:select(dbid) end
+ end
+
+ return ok, err
+end
+
+function _M.keepalivedb(self)
+ local max_idle_timeout = self.idletimeout --ms
+ local pool_size = self.poolsize
+
+ if not pool_size then pool_size = 100 end
+ if not max_idle_timeout then max_idle_timeout = 90000 end --90s
+
+ local ok, err = self.redis:set_keepalive(max_idle_timeout, pool_size)
+ if not ok then
+ ngx.log(ngx.ERR, "redis pool keepalive error",err)
+ return
+ end
+ return
+end
+
+--inner function,only used in this module
+local function _hgetall(red,key)
+ local resp,err = red:hgetall(key)
+ --if not resp or next(resp) == nil then
+ if tbl_isempty(resp) then
+ return nil, "key "..key.." not found"
+ end
+ local hashinfo = red:array_to_hash(resp)
+ return hashinfo,nil
+end
+
+function _M.getserviceinfo(self,key)
+ if not key then
+ return nil,'no key is provided'
+ end
+ local c, err = self:connectdb()
+ if not c then
+ return nil, err
+ end
+
+ local red = self.redis
+ local resp,err = red:get(key) --the key will create dynamically
+ self:keepalivedb()
+ if not resp or resp == ngx.null then
+ return nil, "key "..key.." not found"
+ else
+ return resp,nil
+ end
+end
+
+function _M.getbackservers(self,keypattern)
+ if not keypattern then
+ return nil,'no keypattern is provided'
+ end
+ local c, err = self:connectdb()
+ if not c then
+ return nil, err
+ end
+
+ local red = self.redis
+
+ local resp, err = red:keys(keypattern)
+ if tbl_isempty(resp) then
+ self:keepalivedb()
+ return nil, "no server matched"
+ end
+
+ local servers = {}
+ for i, v in ipairs(resp) do
+ local serverinfo,err = _hgetall(red,v)
+ if serverinfo then
+ tbl_insert(servers,serverinfo)
+ end
+ end
+ self:keepalivedb()
+ return servers,nil
+end
+
+function _M.getcustomsvcnames(self,keypattern)
+ if not keypattern then
+ return nil,'no keypattern is provided'
+ end
+ local c, err = self:connectdb()
+ if not c then
+ return nil, err
+ end
+
+ local red = self.redis
+ --store svc names into the Set
+ local svcname_set={}
+
+ local res, err = red:scan("0","count",50,"match",keypattern)
+ if not res then
+ self:keepalivedb()
+ return {}, "failed to scan in getcustomsvcnames()"
+ end
+
+ local cursor, keys, err = unpack(res)
+ for _, svckey in ipairs(keys) do
+ local m, err = ngx.re.match(svckey, "^.+:custom:([^:]+)", "o")
+ if m then
+ svcname_set[m[1]]=true
+ end
+ end
+
+ while( cursor ~= "0" )
+ do
+ res = red:scan(cursor,"count",50,"match",keypattern)
+ if not res then
+ break
+ end
+ cursor, keys, err = unpack(res)
+ for _, svckey in ipairs(keys) do
+ local m, err = ngx.re.match(svckey, "^.+:custom:([^:]+)", "o")
+ if m then
+ svcname_set[m[1]]=true
+ end
+ end
+ end
+ self:keepalivedb()
+ local svcnames = {}
+ for svcname,_ in pairs(svcname_set) do
+ tbl_insert(svcnames,svcname)
+ end
+ --sort the key_table in reverse order
+ tbl_sort(svcnames, function (a, b)
+ return a > b
+ end)
+ return svcnames,nil
+end
+return _M \ No newline at end of file