Sindbad~EG File Manager

Current Path : /opt/nginxhttpd_/etc/openresty_config/lua/lib/
Upload File :
Current File : //opt/nginxhttpd_/etc/openresty_config/lua/lib/o2switch_cache_wrapper.lua

--[[
    This file contains a cache wrapper module. It will use the cache, if it's configured to do so.
    Allow us to quickly activate/deactivate caching mechanism to test (is the cache worth it ?)
--]]
local _M = {}
local timer = require("resty.timer")
local mlcache = require("resty.mlcache")
local o2config = require "lib/o2switch_config"
local o2debug = require "lib/o2switch_debug"
local table = table
local tostring = tostring
local type = type
local cache, err = nil, nil

if o2config.useInternalCache and not cache then
    --o2debug.debug('Create cache called : ' .. tostring(o2config.internalCacheTtl) .. ',' .. tostring(o2config.internalCacheErrTtl))
    -- @See https://github.com/thibaultcha/lua-resty-mlcache
    cache, err = mlcache.new("my_cache", "cache_dict", {
        lru_size = 100000, -- size of the L1 (Lua VM) cache (nb of items)
        ttl      = o2config.internalCacheTtl,
        neg_ttl  = o2config.internalCacheErrTtl, 
        ipc_shm = 'sync_dict' -- Name of the lua_shared_dict used by the workers sync, to purge/empty L1 cache
    })
    if not cache then
        o2debug.debugErr("Cache : Could not create mlcache." .. (err or ''))
    end
end

--- If the cache is active, purge the cache
-- @return {bool success, string|nil errMsg}
function _M.purgeCache()
    if o2config.useInternalCache == false then
        return true, nil -- Do we return an error or not ? Not sure.
    end

    if not cache then
        --o2debug.debug("purgeCache error : Can't purgeCache, the cache object is null.")
        return false, "Can't purgeCache, the cache object is null."
    end

    local ok, err = cache:purge()
    if not ok then
        --o2debug.debug("purgeCache error : " .. (err or "no err msg"));
        return false, (err or "no err msg")
    end

    return true, nil
end

--- If the cache is active, delete an element from the cache
-- @return {bool success, string|nil errMsg}
function _M.deleteFromCache(key)
    if o2config.useInternalCache == false then
        return true, nil -- Do we return an error or not ? Not sure.
    end

    if type(key) ~= 'string' then
        o2debug.debugErr("deleteFromCache error : Key is not a string, " .. type(key))
        return false, "Key is not a string, " .. type(key)
    end

    if not cache then
        --o2debug.debug("deleteFromCache error : Can't delete an item, the cache object is null.")
        return false, "Can't purgeCache, the cache object is null."
    end

    if not key then
        return false, "The key is null"
    end

    local ok, err = cache:delete(key)
    if not ok then
        --o2debug.debug("deleteFromCache error : " .. (err or "no err msg"));
        return false, (err or "no err msg")
    end

    return true, nil
end

-- If the cache is configured as active, try to retrieve a specific key from the cache
-- Otherwise, it just bypass the cache completely and retrieve fresh data instead
-- @key : the key of the object / stuff to retrieve from the Nginx internal cache
-- @callback : the callback function to call when there is nothing in the cache (or the cache is inactive)
--            The callback must return {data, error|nil}
-- @{...} : the arguments to pass to the callback function
-- @return {data, err|nil}
function _M.get(key, callback, ...)
    local arg={...}
    local val, err = nil, nil

    if type(key) ~= 'string' then
        o2debug.error("get error : Key is not a string, " .. type(key))
        return nil, "Key is not a string, " .. type(key)
    end

    if type(callback) ~= 'function' then
        o2debug.error("Get : The callback is not a function")
        return nil, 'Error : the callback is not a function'
    end

    if not o2config.useInternalCache or cache == nil then
        val, err = callback(table.unpack(arg))
        return val, err
    end

    local value, err, _ = cache:get(key, nil, callback, table.unpack(arg))

    return value, err
end

--- Check if the cache is active, if so, execute the cache invalidation on the Nginx Worker. It will remove the stale
-- elements from the L1 cache. It can (should) be done once per requests.
-- @return {bool success, string|nil errMsg}
function _M.executeInvalidation()
    --o2debug.debug("cache_wrapper.executeInvalidation: Called")

    if o2config.useInternalCache == false then
        return true, nil -- Do we return an error or not ? Not sure.
    end

    if not cache then
        --o2debug.debug("cache_wrapper.executeInvalidation: Can't executeInvalidation, the cache object is null.")
        return false, "Can't executeInvalidation, the cache object is null."
    end

    local ok, err = cache:update(1);
    if not ok then
        --o2debug.debug("cache_wrapper.executeInvalidation:" .. (err or "no err msg"));
        return false, (err or "no err msg")
    end
    --o2debug.debug("cache_wrapper.executeInvalidation: Looks fine")
    return true, nil
end

-- Register one timer per nginx worker that will execute the cache invalidation (if the case is activated)
function _M.registerTimers() 
    --o2debug.debug('cache_wrapper.registerTimers() called')

    if o2config.useInternalCache == false then
        return nil
    end

    timer({
        interval = 10,  
        recurring = true, 
        immediate = false,
        detached = true, 
        jitter = 0.1,
        expire = function() 
            local cacheWrapper = require "lib/o2switch_cache_wrapper"
            cacheWrapper.executeInvalidation()
        end
    })

    return nil
end

return _M

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists