From 4cb99be806a244afe2d42aa0676f08824a4992f2 Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Wed, 9 Sep 2015 10:22:14 +0400 Subject: [PATCH 1/3] Add. Basic cache class Fix. When memcache stopped and mod_memcache loaded dialplan did not build from DB. --- .../resources/scripts/dialplan/dialplan.lua | 30 ++++----- .../scripts/resources/functions/cache.lua | 63 +++++++++++++++++++ 2 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 resources/install/scripts/resources/functions/cache.lua diff --git a/resources/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua b/resources/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua index c838fcf782..232612118d 100644 --- a/resources/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua +++ b/resources/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua @@ -24,15 +24,21 @@ -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. + local cache = require"resources.functions.cache" + --get the cache - if (trim(api:execute("module_exists", "mod_memcache")) == "true") then - XML_STRING = trim(api:execute("memcache", "get dialplan:" .. call_context)); - else - XML_STRING = "-ERR NOT FOUND"; + XML_STRING, err = cache.get("dialplan:" .. call_context) + + if debug['cache'] then + if XML_STRING then + freeswitch.consoleLog("notice", "[xml_handler] dialplan:"..call_context.." source: memcache\n"); + elseif err ~= 'NOT FOUND' then + freeswitch.consoleLog("notice", "[xml_handler] error get element form cache: " .. err .. "\n"); + end end --set the cache - if (XML_STRING == "-ERR NOT FOUND") then + if not XML_STRING then --connect to the database require "resources.functions.database_handle"; @@ -287,8 +293,9 @@ XML_STRING = table.concat(xml, "\n"); --set the cache - tmp = XML_STRING:gsub("\\", "\\\\"); - result = trim(api:execute("memcache", "set dialplan:" .. call_context .. " '"..tmp:gsub("'", "'").."' "..expire["dialplan"])); + if cache.support() then + cache.set("dialplan:" .. call_context, XML_STRING, expire["dialplan"]) + end --send the xml to the console if (debug["xml_string"]) then @@ -304,12 +311,5 @@ --close the database connection dbh:release(); - else - --replace the ' back to a single quote - XML_STRING = XML_STRING:gsub("'", "'"); - - --send to the console - if (debug["cache"]) then - freeswitch.consoleLog("notice", "[xml_handler] dialplan:"..call_context.." source: memcache\n"); - end end + diff --git a/resources/install/scripts/resources/functions/cache.lua b/resources/install/scripts/resources/functions/cache.lua new file mode 100644 index 0000000000..458328a82d --- /dev/null +++ b/resources/install/scripts/resources/functions/cache.lua @@ -0,0 +1,63 @@ +-- @usage cache = require "resources.functions.cache" +-- value = cache.get(key) +-- if not value then +-- ... +-- cache.set(key, value, expire) +-- end +-- + +require "resources.functions.trim"; + +local api = api or freeswitch.API(); + +local Cache = {} + +local function check_error(result) + result = trim(result or '') + + if result and result:sub(1, 4) == '-ERR' then + return nil, trim(result:sub(5)) + end + + if result == 'INVALID COMMAND!' and not Cache.support() then + return nil, 'INVALID COMMAND' + end + + return result +end + +function Cache.support() + -- assume it is not unloadable + if Cache._support then + return true + end + Cache._support = (trim(api:execute('module_exists', 'mod_memcache')) == 'true') + return Cache._support +end + +--- Get element from cache +-- +-- @tparam key string +-- @return[1] string value +-- @return[2] nil +-- @return[2] error string `e.g. 'NOT FOUND' +-- @note error string does not contain `-ERR` prefix +function Cache.get(key) + local result, err = check_error(api:execute('memcache', 'get ' .. key)) + if not result then return nil, err end + return (result:gsub("'", "'")) +end + +function Cache.set(key, value, expire) + value = value:gsub("'", "'"):gsub("\\", "\\\\") + expire = expire and tostring(expire) or "" + return check_error(api:execute("memcache", "set " .. key .. " '" .. value .. "' " .. expire)) +end + +function Cache.del(key) + local result, err = check_error(api:execute("memcache", "set " .. key .. " '" .. value .. "' " .. expire)) + if not result then return nil, err end + return result == '+OK' +end + +return Cache From 528d04b942db624c26a6232af0e5b6161c3c1ce0 Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Wed, 9 Sep 2015 10:45:49 +0400 Subject: [PATCH 2/3] Add. Basic log class. --- .../resources/scripts/dialplan/dialplan.lua | 9 +-- .../scripts/resources/functions/log.lua | 70 +++++++++++++++++++ 2 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 resources/install/scripts/resources/functions/log.lua diff --git a/resources/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua b/resources/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua index 232612118d..5ccc18f06b 100644 --- a/resources/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua +++ b/resources/install/scripts/app/xml_handler/resources/scripts/dialplan/dialplan.lua @@ -25,15 +25,16 @@ -- POSSIBILITY OF SUCH DAMAGE. local cache = require"resources.functions.cache" + local log = require"resources.functions.log"["xml_handler"] --get the cache XML_STRING, err = cache.get("dialplan:" .. call_context) if debug['cache'] then if XML_STRING then - freeswitch.consoleLog("notice", "[xml_handler] dialplan:"..call_context.." source: memcache\n"); + log.notice("dialplan:"..call_context.." source: memcache"); elseif err ~= 'NOT FOUND' then - freeswitch.consoleLog("notice", "[xml_handler] error get element form cache: " .. err .. "\n"); + log.notice("error get element form cache: " .. err); end end @@ -105,7 +106,7 @@ sql = sql .. "ELSE 100 END, "; sql = sql .. "s.dialplan_detail_order asc "; if (debug["sql"]) then - freeswitch.consoleLog("notice", "[xml_handler] SQL: " .. sql .. "\n"); + log.notice("SQL: " .. sql); end x = 0; dbh:query(sql, function(row) @@ -306,7 +307,7 @@ --send to the console if (debug["cache"]) then - freeswitch.consoleLog("notice", "[xml_handler] dialplan:"..call_context.." source: database\n"); + log.notice("dialplan:"..call_context.." source: database"); end --close the database connection diff --git a/resources/install/scripts/resources/functions/log.lua b/resources/install/scripts/resources/functions/log.lua new file mode 100644 index 0000000000..b6cb59652b --- /dev/null +++ b/resources/install/scripts/resources/functions/log.lua @@ -0,0 +1,70 @@ +-- @usage local log = require"resources.functions.log"["xml_handler"] +-- log.notice("hello world") +-- log.noticef("%s %s", "hello", "world") +-- -- log if debug.SQL or debug.xml_handler.SQL then +-- log.tracef("SQL", "SQL is %s", sql) + +local function log(name, level, msg) + freeswitch.consoleLog(level, "[" .. name .. "] " .. msg .. "\n") +end + +local function logf(name, level, ...) + return log(name, level, string.format(...)) +end + +local function trace(type, name, ...) + local t = debug[name] + if t and t[type] ~= nil then + if t[type] then + return log(name, ...) + end + end + if debug[type] then + log(name, ...) + end +end + +local function tracef(type, name, level, ...) + local t = debug[name] + if t and t[type] ~= nil then + if t[type] then + return logf(name, ...) + end + end + if debug[type] then + logf(name, ...) + end +end + +local LEVELS = { + 'error', + 'warning', + 'notice', + 'info', +} + +local TRACE_LEVEL = 'notice' + +local function make_log(name) + local logger = {} + for i = 1, #LEVELS do + logger[ LEVELS[i] ] = function(...) return log(name, LEVELS[i], ...) end; + logger[ LEVELS[i] .. "f" ] = function(...) return logf(name, LEVELS[i], ...) end; + end + + logger.trace = function(type, ...) + trace(type, name, TRACE_LEVEL, ...) + end + + logger.tracef = function(type, ...) + tracef(type, name, TRACE_LEVEL, ...) + end + + return logger +end + +return setmetatable({}, {__index = function(self, name) + local logger = make_log(name) + self[name] = logger + return logger +end}) \ No newline at end of file From dcc08a22650210c319999269f5a1dbc00ea1078b Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Wed, 9 Sep 2015 16:52:52 +0400 Subject: [PATCH 3/3] Fix. Not found is treat as success for delete operation. --- resources/install/scripts/resources/functions/cache.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/resources/install/scripts/resources/functions/cache.lua b/resources/install/scripts/resources/functions/cache.lua index 458328a82d..29c1b9d57e 100644 --- a/resources/install/scripts/resources/functions/cache.lua +++ b/resources/install/scripts/resources/functions/cache.lua @@ -56,7 +56,12 @@ end function Cache.del(key) local result, err = check_error(api:execute("memcache", "set " .. key .. " '" .. value .. "' " .. expire)) - if not result then return nil, err end + if not result then + if err == 'NOT FOUND' then + return true + end + return nil, err + end return result == '+OK' end