Skip to content

Commit

Permalink
optimize: returns a fetch function when creating a new lrucache obj…
Browse files Browse the repository at this point in the history
…ect, which can be used directly to get cached data. (#66)

* optimize: returns a fetch function when creating a new `lrucache`
object, which can be used directly to get cached data.
* test: added test case for `core.lrucache` library.
  • Loading branch information
membphis authored Jun 10, 2019
1 parent ff51c42 commit 10e63c6
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 31 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ logs/*.pid
t/servroot
go
\.*
conf/apisix.uid
11 changes: 4 additions & 7 deletions lua/apisix/balancer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ local balancer = require("ngx.balancer")
local upstreams_etcd
local error = error
local module_name = "balancer"
local lrucache = core.lrucache.new{
plugin_ttl = 300,
plugin_count = 256
}
local lrucache_get = core.lrucache.new({ttl = 300, count = 256})


local _M = {
Expand All @@ -17,8 +14,8 @@ local _M = {


local function create_server_picker(typ, nodes)
-- core.log.info("create create_obj, type: ", typ,
-- " nodes: ", core.json.encode(nodes))
core.log.info("create create_obj, type: ", typ,
" nodes: ", core.json.delay_encode(nodes))

if typ == "roundrobin" then
return roundrobin:new(nodes)
Expand Down Expand Up @@ -61,7 +58,7 @@ function _M.run(route, ctx)
key = upstream.type .. "#route_" .. route.value.id
end

local server_picker = lrucache:plugin(module_name, key, version,
local server_picker = lrucache_get(key, version,
create_server_picker, upstream.type, upstream.nodes)
if not server_picker then
error("failed to fetch server picker")
Expand Down
1 change: 0 additions & 1 deletion lua/apisix/consumer.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
local lrucache = require("apisix.core.lrucache")
local config = require("apisix.core.config_etcd")
local log = require("apisix.core.log")
local insert_tab = table.insert
local consumers
local error = error
Expand Down
50 changes: 27 additions & 23 deletions lua/apisix/core/lrucache.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
-- only support to cache lua table object

local lru_new = require("resty.lrucache").new
local setmetatable = setmetatable
-- todo: support to config it in YAML.
local GLOBAL_TTL = 60 * 60 -- 60 min
local GLOBAL_ITEMS_COUNT = 1024
Expand Down Expand Up @@ -82,29 +81,34 @@ function _M.plugin_ctx(plugin_name, api_ctx, create_obj_fun, ...)
end


local function _obj_plugin_ctx(self, plugin_name, api_ctx, create_obj_fun, ...)
local key = api_ctx.conf_type .. "#" .. api_ctx.conf_id
return _plugin(self.plugin_count, self.plugin_ttl, plugin_name, key,
api_ctx.conf_version, create_obj_fun, ...)
end


local function _obj_plugin(self, plugin_name, key, version, create_obj_fun, ...)
return _plugin(self.plugin_count, self.plugin_ttl, plugin_name, key,
version, create_obj_fun, ...)
end


function _M.new(opts)
local plugin_count = opts and opts.plugin_count or PLUGIN_ITEMS_COUNT
local plugin_ttl = opts and opts.plugin_ttl or PLUGIN_TTL

return setmetatable({
plugin_count = plugin_count,
plugin_ttl = plugin_ttl,
plugin_ctx = _obj_plugin_ctx,
plugin = _obj_plugin,
}, mt)
local item_count = opts and opts.count or GLOBAL_ITEMS_COUNT
local item_ttl = opts and opts.ttl or GLOBAL_TTL

local lru_obj = lru_new(item_count)

return function (key, version, create_obj_fun, ...)
local obj, stale_obj = lru_obj:get(key)
if obj and obj._cache_ver == version then
return obj
end

if stale_obj and stale_obj._cache_ver == version then
lru_obj:set(key, obj, item_ttl)
return stale_obj
end

local err
obj, err = create_obj_fun(...)
if type(obj) == 'table' then
obj._cache_ver = version
lru_obj:set(key, obj, item_ttl)
else
log.warn('only support to cache Lua table object with lrucache')
end

return obj, err
end
end


Expand Down
2 changes: 2 additions & 0 deletions t/core-json.t
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ GET /t
encode: {"test":"test"}
data: test
--- no_error_log
[error]
Expand Down Expand Up @@ -70,3 +71,4 @@ GET /t
--- response_body_like eval
qr/\{"test":"test","fun":"function: 0x[0-9a-f]+"}/
--- no_error_log
[error]
121 changes: 121 additions & 0 deletions t/core-lrucache.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use t::APISix 'no_plan';

repeat_each(1);
no_long_string();
no_root_location();
log_level("info");

run_tests;

__DATA__

=== TEST 1: sanity
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")

local idx = 0
local function create_obj()
idx = idx + 1
return {idx = idx}
end

local obj = core.lrucache.global("key", nil, create_obj)
ngx.say("obj: ", core.json.encode(obj))

obj = core.lrucache.global("key", nil, create_obj)
ngx.say("obj: ", core.json.encode(obj))

obj = core.lrucache.global("key", "1", create_obj)
ngx.say("obj: ", core.json.encode(obj))
}
}
--- request
GET /t
--- response_body
obj: {"idx":1}
obj: {"idx":1}
obj: {"idx":2,"_cache_ver":"1"}
--- no_error_log
[error]



=== TEST 2: plugin
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")

local idx = 0
local function create_obj()
idx = idx + 1
return {idx = idx}
end

local obj = core.lrucache.plugin("plugin-a", "key", nil, create_obj)
ngx.say("obj: ", core.json.encode(obj))

obj = core.lrucache.plugin("plugin-a", "key", nil, create_obj)
ngx.say("obj: ", core.json.encode(obj))

obj = core.lrucache.plugin("plugin-a", "key", "1", create_obj)
ngx.say("obj: ", core.json.encode(obj))

obj = core.lrucache.plugin("plugin-b", "key", "1", create_obj)
ngx.say("obj: ", core.json.encode(obj))
}
}
--- request
GET /t
--- response_body
obj: {"idx":1}
obj: {"idx":1}
obj: {"idx":2,"_cache_ver":"1"}
obj: {"idx":3,"_cache_ver":"1"}
--- no_error_log
[error]



=== TEST 3: new
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")

local idx = 0
local function create_obj()
idx = idx + 1
return {idx = idx}
end

local lru_get = core.lrucache.new()

local obj = lru_get("key", nil, create_obj)
ngx.say("obj: ", core.json.encode(obj))

obj = lru_get("key", nil, create_obj)
ngx.say("obj: ", core.json.encode(obj))

obj = lru_get("key", "1", create_obj)
ngx.say("obj: ", core.json.encode(obj))

obj = lru_get("key", "1", create_obj)
ngx.say("obj: ", core.json.encode(obj))

obj = lru_get("key-different", "1", create_obj)
ngx.say("obj: ", core.json.encode(obj))
}
}
--- request
GET /t
--- response_body
obj: {"idx":1}
obj: {"idx":1}
obj: {"idx":2,"_cache_ver":"1"}
obj: {"idx":2,"_cache_ver":"1"}
obj: {"idx":3,"_cache_ver":"1"}
--- no_error_log
[error]

0 comments on commit 10e63c6

Please sign in to comment.