Skip to content

Commit

Permalink
feat(router) create router in init phase for early error detection
Browse files Browse the repository at this point in the history
We also remember why the router was not created after an invalidation
event so further failed routings will show the reason in the error logs.
  • Loading branch information
thibaultcha committed Jan 12, 2017
1 parent 9e1c27c commit 73bfaf1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 35 deletions.
64 changes: 30 additions & 34 deletions kong/core/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ local certificate = require "kong.core.certificate"
local balancer_execute = require("kong.core.balancer").execute


local router
local router, router_err
local ngx_now = ngx.now
local server_header = _KONG._NAME.."/".._KONG._VERSION

Expand All @@ -28,47 +28,37 @@ local function get_now()
end


local function build_router()
local apis, err = singletons.dao.apis:find_all()
if err then
ngx.log(ngx.CRIT, "[router] could not load APIs: ", err)
return
end
-- in the table below the `before` and `after` is to indicate when they run:
-- before or after the plugins
return {
build_router = function()
local apis

for i = 1, #apis do
-- alias since the router expects 'headers'
-- as a map
if apis[i].hosts then
apis[i].headers = { host = apis[i].hosts }
apis, router_err = singletons.dao.apis:find_all()
if router_err then
return nil, "could not load APIs: " .. router_err
end
end

router, err = Router.new(apis)
if not router then
ngx.log(ngx.CRIT, "[router] could not create router: ", err)
return
end
end
for i = 1, #apis do
-- alias since the router expects 'headers'
-- as a map
if apis[i].hosts then
apis[i].headers = { host = apis[i].hosts }
end
end

router, router_err = Router.new(apis)
if not router then
return nil, "could not create router: " .. router_err
end

return true
end,

-- in the table below the `before` and `after` is to indicate when they run; before or after the plugins
return {
init_worker = {
before = function()
reports.init_worker()
cluster.init_worker()

build_router()

local worker_events = require "resty.worker.events"

worker_events.register(function(data, event, source, pid)
if data and data.collection == "apis" then
--local inspect = require "inspect"
--print("CHANGE IN APIS DATA: ", source, inspect(event), inspect(source), inspect(data))
build_router()
end
end)
end
},
certificate = {
Expand All @@ -78,14 +68,20 @@ return {
},
access = {
before = function()
if not router then
return responses.send_HTTP_INTERNAL_SERVER_ERROR(
"no router to route request (reason: " .. tostring(router_err) .. ")"
)
end

local ctx = ngx.ctx
local var = ngx.var

ctx.KONG_ACCESS_START = get_now()

local api, upstream_scheme, upstream_host, upstream_port = router.exec(ngx)
if not api then
return responses.send_HTTP_NOT_FOUND("no API found")
return responses.send_HTTP_NOT_FOUND("no API found with those values")
end

if api.https_only and not utils.check_https(api.http_if_terminated) then
Expand Down
7 changes: 6 additions & 1 deletion kong/kong.lua
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ function Kong.init()
singletons.configuration = config

attach_hooks(events, require "kong.core.hooks")

assert(core.build_router())
end

function Kong.init_worker()
Expand All @@ -163,7 +165,10 @@ function Kong.init_worker()
local worker_events = require "resty.worker.events"

local handler = function(data, event, source, pid)
if source and source == constants.CACHE.CLUSTER then
if data and data.collection == "apis" then
assert(core.build_router())

elseif source and source == constants.CACHE.CLUSTER then
singletons.events:publish(event, data)
end
end
Expand Down

0 comments on commit 73bfaf1

Please sign in to comment.