Skip to content

Commit

Permalink
optimize(router): used local cache variable to avoid one lrucache call.
Browse files Browse the repository at this point in the history
  • Loading branch information
membphis committed Aug 4, 2019
1 parent 66ac7ed commit 1ce9883
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 76 deletions.
86 changes: 46 additions & 40 deletions lua/apisix/http/router/r3_host_uri.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,50 @@ local ipairs = ipairs
local type = type
local error = error
local str_reverse = string.reverse
local routes
local user_routes
local cached_version


local _M = {version = 0.1}
local _M = {version = 0.2}

local api_routes = {}
local api_router
local function create_api_router()
local api_routes = plugin.api_routes()
core.table.clear(api_routes)
local only_uri_routes = {}
local only_uri_router
local function create_only_uri_router()
local routes = plugin.api_routes()

local idx = 0
for _, route in ipairs(api_routes) do
for _, route in ipairs(routes) do
if type(route) == "table" then
idx = idx + 1
api_routes[idx] = {
core.table.insert(only_uri_routes, {
path = route.uri,
handler = route.handler,
method = route.methods,
}
})
end
end

api_router = r3router.new(api_routes)
api_router:compile()
only_uri_router = r3router.new(only_uri_routes)
only_uri_router:compile()
return true
end


local req_routes = {}
local req_routes_idx = 0
local host_uri_routes = {}
local host_uri_router
local function push_valid_route(route)
if type(route) ~= "table" then
return
end

local host = route.value.host
if not host then
core.log.error("missing `host` field in route: ",
core.json.delay_encode(route))
core.table.insert(only_uri_routes, {
path = route.value.uri,
method = route.value.methods,
handler = function (params, api_ctx)
api_ctx.matched_params = params
api_ctx.matched_route = route
end
})
return
end

Expand All @@ -57,55 +61,57 @@ local function push_valid_route(route)
end

core.log.info("route rule: ", host .. route.value.uri)
req_routes_idx = req_routes_idx + 1
req_routes[req_routes_idx] = {
core.table.insert(host_uri_routes, {
path = "/" .. host .. route.value.uri,
method = route.value.methods,
handler = function (params, api_ctx)
api_ctx.matched_params = params
api_ctx.matched_route = route
end
}
})

return
end

local function create_r3_router(routes)
create_api_router()

core.table.clear(req_routes)
req_routes_idx = 0
core.table.clear(only_uri_routes)
core.table.clear(host_uri_routes)

for _, route in ipairs(routes or {}) do
push_valid_route(route)
end

core.log.info("route items: ", core.json.delay_encode(req_routes, true))
local r3 = r3router.new(req_routes)
r3:compile()
return r3
create_only_uri_router()

core.log.info("route items: ",
core.json.delay_encode(host_uri_routes, true))
host_uri_router = r3router.new(host_uri_routes)
host_uri_router:compile()
end


local match_opts = {}
function _M.match(api_ctx)
local router, err = core.lrucache.global("/routes", routes.conf_version,
create_r3_router, routes.values)
if not router then
core.log.error("failed to fetch http router: ", err)
if not cached_version or cached_version ~= user_routes.conf_version then
create_r3_router(user_routes.values)
cached_version = user_routes.conf_version
end

if not host_uri_router then
core.log.error("failed to fetch valid `host+uri` router: ")
return core.response.exit(404)
end

core.table.clear(match_opts)
match_opts.method = api_ctx.var.method

local host_uri = "/" .. str_reverse(api_ctx.var.host) .. api_ctx.var.uri
local ok = router:dispatch2(nil, host_uri, match_opts, api_ctx)
local ok = host_uri_router:dispatch2(nil, host_uri, match_opts, api_ctx)
if ok then
return true
end

ok = router:dispatch2(nil, api_ctx.var.uri, match_opts, api_ctx)
ok = only_uri_router:dispatch2(nil, api_ctx.var.uri, match_opts, api_ctx)
if ok then
return true
end
Expand All @@ -116,22 +122,22 @@ end


function _M.routes()
if not routes then
if not user_routes then
return nil, nil
end

return routes.values, routes.conf_version
return user_routes.values, user_routes.conf_version
end


function _M.init_worker()
local err
routes, err = core.config.new("/routes", {
user_routes, err = core.config.new("/routes", {
automatic = true,
item_schema = core.schema.route
})
if not routes then
error("failed to create etcd instance for fetching routes : " .. err)
if not user_routes then
error("failed to create etcd instance for fetching /routes : " .. err)
end
end

Expand Down
59 changes: 29 additions & 30 deletions lua/apisix/http/router/r3_uri.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,68 +7,68 @@ local plugin = require("apisix.plugin")
local ipairs = ipairs
local type = type
local error = error
local routes
local user_routes
local cached_version


local _M = {version = 0.1}


local empty_tab = {}
local route_items
local uri_routes = {}
local uri_router
local function create_r3_router(routes)
routes = routes or empty_tab
routes = routes or {}

local api_routes = plugin.api_routes()
route_items = core.table.new(#api_routes + #routes, 0)
local idx = 0
core.table.clear(uri_routes)

for _, route in ipairs(api_routes) do
if type(route) == "table" then
idx = idx + 1
route_items[idx] = {
core.table.insert(uri_routes, {
path = route.uri,
handler = route.handler,
method = route.methods,
}
})
end
end

for _, route in ipairs(routes) do
if type(route) == "table" then
idx = idx + 1
route_items[idx] = {
core.table.insert(uri_routes, {
path = route.value.uri,
method = route.value.methods,
host = route.value.host,
handler = function (params, api_ctx)
api_ctx.matched_params = params
api_ctx.matched_route = route
end
}
})
end
end

core.log.info("route items: ", core.json.delay_encode(route_items, true))
local r3 = r3router.new(route_items)
r3:compile()
return r3
core.log.info("route items: ", core.json.delay_encode(uri_routes, true))
uri_router = r3router.new(uri_routes)
uri_router:compile()
end


local match_opts = {}
function _M.match(api_ctx)
local router, err = core.lrucache.global("/routes", routes.conf_version,
create_r3_router, routes.values)
if not router then
core.log.error("failed to fetch http router: ", err)
if not cached_version or cached_version ~= user_routes.conf_version then
create_r3_router(user_routes.values)
cached_version = user_routes.conf_version
end

if not uri_router then
core.log.error("failed to fetch valid `uri` router: ")
return core.response.exit(404)
end

core.table.clear(match_opts)
match_opts.method = api_ctx.var.method
match_opts.host = api_ctx.var.host

local ok = router:dispatch2(nil, api_ctx.var.uri, match_opts, api_ctx)
local ok = uri_router:dispatch2(nil, api_ctx.var.uri, match_opts, api_ctx)
if not ok then
core.log.info("not find any matched route")
return core.response.exit(404)
Expand All @@ -79,23 +79,22 @@ end


function _M.routes()
if not routes then
if not user_routes then
return nil, nil
end

return routes.values, routes.conf_version
return user_routes.values, user_routes.conf_version
end


function _M.init_worker()
local err
routes, err = core.config.new("/routes",
{
automatic = true,
item_schema = core.schema.route
})
if not routes then
error("failed to create etcd instance for fetching routes : " .. err)
user_routes, err = core.config.new("/routes", {
automatic = true,
item_schema = core.schema.route
})
if not user_routes then
error("failed to create etcd instance for fetching /routes : " .. err)
end
end

Expand Down
8 changes: 2 additions & 6 deletions t/node/match-host-uri.t
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ moc.oof/hello
},
"type": "roundrobin"
},
"host": "foo.com",
"uri": "/server_port"
}]]
)
Expand All @@ -164,8 +163,6 @@ passed
--- request
GET /hello
--- yaml_config eval: $::yaml_config
--- more_headers
Host: foo.com
--- error_code: 404
--- response_body eval
qr/404 Not Found/
Expand All @@ -179,7 +176,7 @@ qr/404 Not Found/
GET /server_port
--- yaml_config eval: $::yaml_config
--- more_headers
Host: foo.com
Host: anydomain.com
--- response_body_like eval
qr/1981/
--- no_error_log
Expand All @@ -202,7 +199,6 @@ qr/1981/
},
"type": "roundrobin"
},
"host": "foo.com",
"uri": "/hello"
}]]
)
Expand Down Expand Up @@ -240,7 +236,7 @@ qr/404 Not Found/
GET /hello
--- yaml_config eval: $::yaml_config
--- more_headers
Host: foo.com
Host: anydomain.com
--- response_body
hello world
--- no_error_log
Expand Down

0 comments on commit 1ce9883

Please sign in to comment.