Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change: make lrucache lock optional #2575

Merged
merged 2 commits into from
Nov 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 38 additions & 29 deletions apisix/core/lrucache.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

local lru_new = require("resty.lrucache").new
local resty_lock = require("resty.lock")
local log = require("apisix.core.log")
local tostring = tostring
local concat = table.concat
local ngx = ngx
local get_phase = ngx.get_phase

Expand Down Expand Up @@ -65,14 +67,22 @@ end


local function new_lru_fun(opts)
local item_count = opts and opts.count or GLOBAL_ITEMS_COUNT
local item_ttl = opts and opts.ttl or GLOBAL_TTL
local item_count, item_ttl
if opts and opts.type == 'plugin' then
item_count = opts.count or PLUGIN_ITEMS_COUNT
item_ttl = opts.ttl or PLUGIN_TTL
else
item_count = opts and opts.count or GLOBAL_ITEMS_COUNT
item_ttl = opts and opts.ttl or GLOBAL_TTL
end

local item_release = opts and opts.release
local invalid_stale = opts and opts.invalid_stale
local serial_creating = opts and opts.serial_creating
local lru_obj = lru_new(item_count)

return function (key, version, create_obj_fun, ...)
if not can_yield_phases[get_phase()] then
if not serial_creating or not can_yield_phases[get_phase()] then
local cache_obj = fetch_valid_cache(lru_obj, invalid_stale,
item_ttl, item_release, key, version)
if cache_obj then
Expand All @@ -99,6 +109,8 @@ local function new_lru_fun(opts)
end

local key_s = tostring(key)
log.info("try to lock with key ", key_s)

local elapsed, err = lock:lock(key_s)
if not elapsed then
return nil, "failed to acquire the lock: " .. err
Expand All @@ -108,6 +120,7 @@ local function new_lru_fun(opts)
nil, key, version)
if cache_obj then
lock:unlock()
log.info("unlock with key ", key_s)
return cache_obj.val
end

Expand All @@ -116,6 +129,7 @@ local function new_lru_fun(opts)
lru_obj:set(key, {val = obj, ver = version}, item_ttl)
end
lock:unlock()
log.info("unlock with key ", key_s)

return obj, err
end
Expand All @@ -125,42 +139,37 @@ end
global_lru_fun = new_lru_fun()


local function _plugin(plugin_name, key, version, create_obj_fun, ...)
local lru_global = global_lru_fun("/plugin/" .. plugin_name, nil,
lru_new, PLUGIN_ITEMS_COUNT)

local obj, stale_obj = lru_global:get(key)
if obj and obj.ver == version then
return obj.val
end

if stale_obj and stale_obj.ver == version then
lru_global:set(key, stale_obj, PLUGIN_TTL)
return stale_obj
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we need to return stale_obj.val instead. Otherwise, the returned value will be:

ver = xxx,
val = actual_cache_obj,

end
local plugin_ctx
do
local key_buf = {
nil,
nil,
nil,
}

function plugin_ctx(lrucache, api_ctx, extra_key, create_obj_func, ...)
key_buf[1] = api_ctx.conf_type
key_buf[2] = api_ctx.conf_id

local key
if extra_key then
key_buf[3] = extra_key
key = concat(key_buf, "#", 1, 3)
else
key = concat(key_buf, "#", 1, 2)
end

local err
obj, err = create_obj_fun(...)
if obj ~= nil then
lru_global:set(key, {val = obj, ver = version}, PLUGIN_TTL)
return lrucache(key, api_ctx.conf_version, create_obj_func, ...)
end

return obj, err
end


local _M = {
version = 0.1,
new = new_lru_fun,
global = global_lru_fun,
plugin = _plugin,
plugin_ctx = plugin_ctx,
}


function _M.plugin_ctx(plugin_name, api_ctx, create_obj_fun, ...)
local key = api_ctx.conf_type .. "#" .. api_ctx.conf_id
return _plugin(plugin_name, key, api_ctx.conf_version, create_obj_fun, ...)
end


return _M
9 changes: 6 additions & 3 deletions apisix/plugins/basic-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ local consumer = require("apisix.consumer")
local lrucache = core.lrucache.new({
ttl = 300, count = 512
})
local consumers_lrucache = core.lrucache.new({
type = "plugin",
})

local schema = {
type = "object",
Expand Down Expand Up @@ -143,9 +146,9 @@ function _M.access(conf, ctx)
return 401, { message = "Missing related consumer" }
end

local consumers = core.lrucache.plugin(plugin_name, "consumers_key",
consumer_conf.conf_version,
create_consume_cache, consumer_conf)
local consumers = consumers_lrucache("consumers_key",
consumer_conf.conf_version,
create_consume_cache, consumer_conf)

-- 3. check user exists
local cur_consumer = consumers[username]
Expand Down
7 changes: 6 additions & 1 deletion apisix/plugins/cors.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ local plugin_name = "cors"
local str_find = string.find
local re_gmatch = ngx.re.gmatch


local lrucache = core.lrucache.new({
type = "plugin",
})

local schema = {
type = "object",
properties = {
Expand Down Expand Up @@ -160,7 +165,7 @@ function _M.header_filter(conf, ctx)
if allow_origins == "**" then
allow_origins = req_origin or '*'
end
local multiple_origin, err = core.lrucache.plugin_ctx(plugin_name, ctx,
local multiple_origin, err = core.lrucache.plugin_ctx(lrucache, ctx, nil,
create_mutiple_origin_cache, conf)
if err then
return 500, {message = "get mutiple origin cache failed: " .. err}
Expand Down
9 changes: 6 additions & 3 deletions apisix/plugins/hmac-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ local ACCESS_KEY = "X-HMAC-ACCESS-KEY"
local SIGNED_HEADERS_KEY = "X-HMAC-SIGNED-HEADERS"
local plugin_name = "hmac-auth"

local lrucache = core.lrucache.new({
type = "plugin",
})

local schema = {
type = "object",
title = "work with route or service object",
Expand Down Expand Up @@ -174,9 +178,8 @@ local function get_consumer(access_key)
return nil, {message = "Missing related consumer"}
end

local consumers = core.lrucache.plugin(plugin_name, "consumers_key",
consumer_conf.conf_version,
create_consumer_cache, consumer_conf)
local consumers = lrucache("consumers_key", consumer_conf.conf_version,
create_consumer_cache, consumer_conf)

local consumer = consumers[access_key]
if not consumer then
Expand Down
14 changes: 8 additions & 6 deletions apisix/plugins/jwt-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ local sub_str = string.sub
local plugin_name = "jwt-auth"


local lrucache = core.lrucache.new({
type = "plugin",
})

local schema = {
type = "object",
additionalProperties = false,
Expand Down Expand Up @@ -173,9 +177,8 @@ function _M.rewrite(conf, ctx)
return 401, {message = "Missing related consumer"}
end

local consumers = core.lrucache.plugin(plugin_name, "consumers_key",
consumer_conf.conf_version,
create_consume_cache, consumer_conf)
local consumers = lrucache("consumers_key", consumer_conf.conf_version,
create_consume_cache, consumer_conf)

local consumer = consumers[user_key]
if not consumer then
Expand Down Expand Up @@ -210,9 +213,8 @@ local function gen_token()
return core.response.exit(404)
end

local consumers = core.lrucache.plugin(plugin_name, "consumers_key",
consumer_conf.conf_version,
create_consume_cache, consumer_conf)
local consumers = lrucache("consumers_key", consumer_conf.conf_version,
create_consume_cache, consumer_conf)

core.log.info("consumers: ", core.json.delay_encode(consumers))
local consumer = consumers[key]
Expand Down
9 changes: 6 additions & 3 deletions apisix/plugins/key-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ local plugin_name = "key-auth"
local ipairs = ipairs


local lrucache = core.lrucache.new({
type = "plugin",
})

local schema = {
type = "object",
properties = {
Expand Down Expand Up @@ -73,9 +77,8 @@ function _M.rewrite(conf, ctx)
return 401, {message = "Missing related consumer"}
end

local consumers = core.lrucache.plugin(plugin_name, "consumers_key",
consumer_conf.conf_version,
create_consume_cache, consumer_conf)
local consumers = lrucache("consumers_key", consumer_conf.conf_version,
create_consume_cache, consumer_conf)

local consumer = consumers[key]
if not consumer then
Expand Down
6 changes: 5 additions & 1 deletion apisix/plugins/limit-conn.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ local sleep = core.sleep
local plugin_name = "limit-conn"


local lrucache = core.lrucache.new({
type = "plugin",
})

local schema = {
type = "object",
properties = {
Expand Down Expand Up @@ -61,7 +65,7 @@ end

function _M.access(conf, ctx)
core.log.info("ver: ", ctx.conf_version)
local lim, err = core.lrucache.plugin_ctx(plugin_name, ctx,
local lim, err = core.lrucache.plugin_ctx(lrucache, ctx, nil,
create_limit_obj, conf)
if not lim then
core.log.error("failed to instantiate a resty.limit.conn object: ", err)
Expand Down
6 changes: 4 additions & 2 deletions apisix/plugins/limit-count.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ do
local cluster_src = "apisix.plugins.limit-count.limit-count-redis-cluster"
limit_redis_cluster_new = require(cluster_src).new
end
local lrucache = core.lrucache.new({
type = 'plugin', serial_creating = true,
})


local schema = {
Expand Down Expand Up @@ -154,8 +157,7 @@ end

function _M.access(conf, ctx)
core.log.info("ver: ", ctx.conf_version)
local lim, err = core.lrucache.plugin_ctx(plugin_name, ctx,
create_limit_obj, conf)
local lim, err = core.lrucache.plugin_ctx(lrucache, ctx, conf.policy, create_limit_obj, conf)
if not lim then
core.log.error("failed to fetch limit.count object: ", err)
return 500
Expand Down
8 changes: 6 additions & 2 deletions apisix/plugins/limit-req.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ local plugin_name = "limit-req"
local sleep = core.sleep


local lrucache = core.lrucache.new({
type = "plugin",
})

local schema = {
type = "object",
properties = {
Expand Down Expand Up @@ -60,8 +64,8 @@ end


function _M.access(conf, ctx)
local lim, err = core.lrucache.plugin_ctx(plugin_name, ctx,
create_limit_obj, conf)
local lim, err = core.lrucache.plugin_ctx(lrucache, ctx, nil,
create_limit_obj, conf)
if not lim then
core.log.error("failed to instantiate a resty.limit.req object: ", err)
return 500
Expand Down
7 changes: 6 additions & 1 deletion apisix/plugins/serverless.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ local type = type
return function(plugin_name, priority)
local core = require("apisix.core")


local lrucache = core.lrucache.new({
type = "plugin",
})

local schema = {
type = "object",
properties = {
Expand Down Expand Up @@ -66,7 +71,7 @@ return function(plugin_name, priority)
return
end

local functions = core.lrucache.plugin_ctx(plugin_name, ctx,
local functions = core.lrucache.plugin_ctx(lrucache, ctx, nil,
load_funcs, conf.functions)

for _, func in ipairs(functions) do
Expand Down
8 changes: 3 additions & 5 deletions apisix/plugins/syslog.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ local schema = {


local lrucache = core.lrucache.new({
ttl = 300, count = 512
ttl = 300, count = 512, serial_creating = true,
})


Expand Down Expand Up @@ -83,10 +83,8 @@ local function send_syslog_data(conf, log_message, api_ctx)
local res = true

-- fetch it from lrucache
local logger, err = lrucache(
api_ctx.conf_type .. "#" .. api_ctx.conf_id,
api_ctx.conf_version,
logger_socket.new, logger_socket, {
local logger, err = core.lrucache.plugin_ctx(
lrucache, api_ctx, nil, logger_socket.new, logger_socket, {
host = conf.host,
port = conf.port,
flush_limit = conf.flush_limit,
Expand Down
14 changes: 8 additions & 6 deletions apisix/plugins/wolf-rbac.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ local string = string
local plugin_name = "wolf-rbac"


local lrucache = core.lrucache.new({
type = "plugin",
})

local schema = {
type = "object",
properties = {
Expand Down Expand Up @@ -274,9 +278,8 @@ function _M.rewrite(conf, ctx)
return 401, fail_response("Missing related consumer")
end

local consumers = core.lrucache.plugin(plugin_name, "consumers_key",
consumer_conf.conf_version,
create_consume_cache, consumer_conf)
local consumers = lrucache("consumers_key", consumer_conf.conf_version,
create_consume_cache, consumer_conf)

core.log.info("------ consumers: ", core.json.delay_encode(consumers))
local consumer = consumers[appid]
Expand Down Expand Up @@ -344,9 +347,8 @@ local function get_consumer(appid)
core.response.exit(500)
end

local consumers = core.lrucache.plugin(plugin_name, "consumers_key",
consumer_conf.conf_version,
create_consume_cache, consumer_conf)
local consumers = lrucache("consumers_key", consumer_conf.conf_version,
create_consume_cache, consumer_conf)

core.log.info("------ consumers: ", core.json.delay_encode(consumers))
local consumer = consumers[appid]
Expand Down
Loading