From db4a7a339536e2420a96c226fbf08ce535a712f6 Mon Sep 17 00:00:00 2001 From: kingluo Date: Fri, 23 Dec 2022 11:41:59 +0800 Subject: [PATCH 1/2] bugfix: unregister timer when snowflake etcd keepalive failed --- apisix/plugins/request-id.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/apisix/plugins/request-id.lua b/apisix/plugins/request-id.lua index 353bd3f8322e..ceddcdf94969 100644 --- a/apisix/plugins/request-id.lua +++ b/apisix/plugins/request-id.lua @@ -129,6 +129,7 @@ local function gen_data_machine(max_number) if err4 then snowflake_inited = nil data_machine = nil + timers.unregister_timer("plugin#request-id") core.log.error("snowflake data_machine: " .. id .." lease failed.") end start_at = now From 9ee87dafb59e45ba50d710a8e27a36073f886855 Mon Sep 17 00:00:00 2001 From: kingluo Date: Fri, 23 Dec 2022 16:24:22 +0800 Subject: [PATCH 2/2] add test case --- t/plugin/request-id-reload-bugfix.t | 117 ++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 t/plugin/request-id-reload-bugfix.t diff --git a/t/plugin/request-id-reload-bugfix.t b/t/plugin/request-id-reload-bugfix.t new file mode 100644 index 000000000000..71775e7d9b62 --- /dev/null +++ b/t/plugin/request-id-reload-bugfix.t @@ -0,0 +1,117 @@ +# +# 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. +# +use t::APISIX 'no_plan'; + +log_level('warn'); +repeat_each(1); +no_long_string(); +no_root_location(); + +add_block_preprocessor(sub { + my ($block) = @_; + + if (!$block->request) { + $block->set_value("request", "GET /t"); + } + + my $extra_init_by_lua = <<_EOC_; + local core = require("apisix.core") + local orig_new = core.etcd.new + core.etcd.new = function(...) + local cli, prefix = orig_new(...) + cli.keepalive = function(...) + return false, "test error" + end + -- only simulate error once + -- because reload would redo init() + core.etcd.new = orig_new + return cli, prefix + end + + local timers = require("apisix.timers") + local orig_unregister = timers.unregister_timer + unregister_cnt = 0 + timers.unregister_timer = function(name, privileged) + core.log.error("unregister timer: ", name) + unregister_cnt = unregister_cnt + 1 + return orig_unregister(name, privileged) + end +_EOC_ + + $block->set_value("extra_init_by_lua", $extra_init_by_lua); +}); + +run_tests; + +__DATA__ + +=== TEST 1: unregister timer when etcd keepalive failed +--- yaml_config +plugins: + - request-id +plugin_attr: + request-id: + snowflake: + enable: true + data_machine_interval: 1 +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "request-id": { + "algorithm": "snowflake" + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1982": 1 + }, + "type": "roundrobin" + }, + "uri": "/opentracing" + }]] + ) + if code >= 300 then + ngx.status = code + return + end + + -- wait for keepalive fails + ngx.sleep(2) + + local code = t('/apisix/admin/plugins/reload', + ngx.HTTP_PUT) + if code >= 300 then + ngx.status = code + return + end + + ngx.sleep(2) + ngx.log(ngx.ERR, unregister_cnt) + if unregister_cnt ~= 1 then + ngx.status = 500 + end + } + } +--- timeout: 5 +--- error_log +lease failed +unregister timer: plugin#request-id