diff --git a/apisix/core.lua b/apisix/core.lua index f421716e6bdc..7e317f7e553b 100644 --- a/apisix/core.lua +++ b/apisix/core.lua @@ -54,4 +54,5 @@ return { os = require("apisix.core.os"), pubsub = require("apisix.core.pubsub"), math = require("apisix.core.math"), + event = require("apisix.core.event"), } diff --git a/apisix/core/event.lua b/apisix/core/event.lua new file mode 100644 index 000000000000..38459ff11060 --- /dev/null +++ b/apisix/core/event.lua @@ -0,0 +1,41 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +local CONST = { + BUILD_ROUTER = 1, +} + +local _M = { + CONST = CONST, +} + +local events = {} + + +function _M.push(type, ...) + local handler = events[type] + if handler then + handler(...) + end +end + +function _M.register(type, handler) + -- TODO: we can register more than one handler + events[type] = handler +end + +return _M diff --git a/apisix/http/route.lua b/apisix/http/route.lua index 28e121708dc3..6292b577a071 100644 --- a/apisix/http/route.lua +++ b/apisix/http/route.lua @@ -21,7 +21,7 @@ local service_fetch = require("apisix.http.service").get local core = require("apisix.core") local expr = require("resty.expr.v1") local plugin_checker = require("apisix.plugin").plugin_checker -local ai = require("apisix.core.ai") +local event = require("apisix.core.event") local ipairs = ipairs local type = type local error = error @@ -92,7 +92,7 @@ function _M.create_radixtree_uri_router(routes, uri_routes, with_parameter) end end - ai.routes_analyze(uri_routes) + event.push(event.CONST.BUILD_ROUTER, uri_routes) core.log.info("route items: ", core.json.delay_encode(uri_routes, true)) if with_parameter then diff --git a/apisix/init.lua b/apisix/init.lua index 04920196d24b..2030e0241d51 100644 --- a/apisix/init.lua +++ b/apisix/init.lua @@ -152,6 +152,8 @@ function _M.http_init_worker() apisix_upstream.init_worker() require("apisix.plugins.ext-plugin.init").init_worker() + -- TODO: need to revisit code layering and avoid similar hacking + require("apisix.plugins.ai").init_worker() local_conf = core.config.local_conf() diff --git a/apisix/core/ai.lua b/apisix/plugins/ai.lua similarity index 82% rename from apisix/core/ai.lua rename to apisix/plugins/ai.lua index 57a8a60e0e1b..6b60aac29c1f 100644 --- a/apisix/core/ai.lua +++ b/apisix/plugins/ai.lua @@ -16,6 +16,8 @@ -- local require = require local core = require("apisix.core") +local router = require("apisix.router") +local event = require("apisix.core.event") local ipairs = ipairs local pcall = pcall local loadstring = loadstring @@ -43,10 +45,20 @@ local route_lrucache = core.lrucache.new({ count = 512 }) -local _M = {} +local schema = {} + +local plugin_name = "ai" + +local _M = { + version = 0.1, + priority = 25000, + name = plugin_name, + schema = schema, + scope = "global", +} local orig_router_match -local router + local function match_route(ctx) orig_router_match(ctx) @@ -57,7 +69,7 @@ end local function ai_match(ctx) local key = get_cache_key_func(ctx) core.log.info("route cache key: ", core.log.delay_exec(encode_base64, key)) - local ver = router.user_routes.conf_version + local ver = router.router_http.user_routes.conf_version local route_cache = route_lrucache(key, ver, match_route, ctx) -- if the version has not changed, use the cached route @@ -89,8 +101,8 @@ local function gen_get_cache_key_func(route_flags) end -function _M.routes_analyze(routes) - -- TODO: we need to add a option in config.yaml to enable this feature(default is true) +local function routes_analyze(routes) + -- TODO: need to add a option in config.yaml to enable this feature(default is true) local route_flags = core.table.new(0, 2) for _, route in ipairs(routes) do if route.methods then @@ -116,23 +128,27 @@ function _M.routes_analyze(routes) if route_flags["vars"] or route_flags["filter_fun"] or route_flags["remote_addr"] then - router.match = orig_router_match + router.router_http.match = orig_router_match else core.log.info("use ai plane to match route") - router.match = ai_match + router.router_http.match = ai_match local ok, err = gen_get_cache_key_func(route_flags) if not ok then core.log.error("generate get_cache_key_func failed:", err) - router.match = orig_router_match + router.router_http.match = orig_router_match end end end -function _M.init_worker(router_http) - router = router_http - orig_router_match = router.match +function _M.init() + event.register(event.CONST.BUILD_ROUTER, routes_analyze) +end + + +function _M.init_worker() + orig_router_match = router.router_http.match end return _M diff --git a/apisix/router.lua b/apisix/router.lua index 4b6ed6c32600..9bdafebbdb6e 100644 --- a/apisix/router.lua +++ b/apisix/router.lua @@ -19,7 +19,6 @@ local http_route = require("apisix.http.route") local apisix_upstream = require("apisix.upstream") local core = require("apisix.core") local plugin_checker = require("apisix.plugin").plugin_checker -local ai_init = require("apisix.core.ai").init_worker local str_lower = string.lower local error = error local ipairs = ipairs @@ -84,7 +83,6 @@ function _M.http_init_worker() local router_http = require("apisix.http.router." .. router_http_name) attach_http_router_common_methods(router_http) - ai_init(router_http) router_http.init_worker(filter) _M.router_http = router_http diff --git a/conf/config-default.yaml b/conf/config-default.yaml index 526c65866018..bad0e41e4c1d 100755 --- a/conf/config-default.yaml +++ b/conf/config-default.yaml @@ -389,6 +389,7 @@ graphql: #cmd: ["ls", "-l"] plugins: # plugin list (sorted by priority) + - ai # priority: 25000 - real-ip # priority: 23000 - client-control # priority: 22000 - proxy-control # priority: 21990 diff --git a/t/admin/plugins.t b/t/admin/plugins.t index b13919138f08..74827e437ebf 100644 --- a/t/admin/plugins.t +++ b/t/admin/plugins.t @@ -61,6 +61,7 @@ __DATA__ } --- response_body +ai real-ip client-control proxy-control diff --git a/t/core/config.t b/t/core/config.t index 29d1cc52dc07..18191dae724f 100644 --- a/t/core/config.t +++ b/t/core/config.t @@ -38,7 +38,7 @@ __DATA__ GET /t --- response_body etcd host: http://127.0.0.1:2379 -first plugin: "real-ip" +first plugin: "ai" diff --git a/t/core/ai.t b/t/plugin/ai.t similarity index 99% rename from t/core/ai.t rename to t/plugin/ai.t index 14d4e7b10273..3c0cd62d97e0 100644 --- a/t/core/ai.t +++ b/t/plugin/ai.t @@ -130,7 +130,6 @@ use ai plane to match route if i == 1 then -- arg_k = a, match route res, err = httpc:request_uri(uri1) - ngx.log(ngx.WARN, "res : ", require("inspect")(res)) assert(res.status == 200) else -- arg_k = v, not match route