You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by we...@apache.org on 2020/09/17 01:30:59 UTC
[apisix] branch master updated: bugfix: clear all cached object
when got `delete` action, and removing (#2168)
This is an automated email from the ASF dual-hosted git repository.
wenming pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 68b1f9c bugfix: clear all cached object when got `delete` action, and removing (#2168)
68b1f9c is described below
commit 68b1f9cc57c3320ff814859ce66f4cfd401e10ae
Author: YuanSheng Wang <me...@gmail.com>
AuthorDate: Thu Sep 17 09:30:44 2020 +0800
bugfix: clear all cached object when got `delete` action, and removing (#2168)
stale boolean data in table `self.values` with a safer way.
---
apisix/core/config_etcd.lua | 25 ++++++----
t/node/route-delete.t | 109 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 126 insertions(+), 8 deletions(-)
diff --git a/apisix/core/config_etcd.lua b/apisix/core/config_etcd.lua
index b651ea9..d058277 100644
--- a/apisix/core/config_etcd.lua
+++ b/apisix/core/config_etcd.lua
@@ -14,6 +14,8 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
+
+local table = require("apisix.core.table")
local config_local = require("apisix.core.config_local")
local log = require("apisix.core.log")
local json = require("apisix.core.json")
@@ -338,10 +340,13 @@ local function sync_data(self)
res.value.id = key
self.values[pre_index] = res
res.clean_handlers = {}
+ log.info("update data by key: ", key)
else
self.sync_times = self.sync_times + 1
self.values[pre_index] = false
+ self.values_hash[key] = nil
+ log.info("delete data by key: ", key)
end
elseif res.value then
@@ -349,25 +354,29 @@ local function sync_data(self)
insert_tab(self.values, res)
self.values_hash[key] = #self.values
res.value.id = key
+ log.info("insert data by key: ", key)
end
-- avoid space waste
- -- todo: need to cover this path, it is important.
if self.sync_times > 100 then
- local count = 0
- for i = 1, #self.values do
- local val = self.values[i]
- self.values[i] = nil
+ local values_original = table.clone(self.values)
+ table.clear(self.values)
+
+ for i = 1, #values_original do
+ local val = values_original[i]
if val then
- count = count + 1
- self.values[count] = val
+ table.insert(self.values, val)
end
end
- for i = 1, count do
+ table.clear(self.values_hash)
+ log.info("clear stale data in `values_hash` for key: ", key)
+
+ for i = 1, #self.values do
key = short_key(self, self.values[i].key)
self.values_hash[key] = i
end
+
self.sync_times = 0
end
diff --git a/t/node/route-delete.t b/t/node/route-delete.t
new file mode 100644
index 0000000..2111198
--- /dev/null
+++ b/t/node/route-delete.t
@@ -0,0 +1,109 @@
+#
+# 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';
+
+repeat_each(2);
+log_level('info');
+worker_connections(256);
+no_root_location();
+no_shuffle();
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: create 130 routes + delete them
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+
+ for i = 1, 130 do
+ local code, body = t('/apisix/admin/routes/' .. i,
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello]] .. i .. [["
+ }]]
+ )
+ end
+
+ for i = 1, 130 do
+ local code, body = t('/apisix/admin/routes/' .. i,
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello]] .. i .. [["
+ }]]
+ )
+ end
+
+ for i = 1, 130 do
+ local code, body = t('/apisix/admin/routes/' .. i,
+ ngx.HTTP_DELETE
+ )
+ end
+
+ for i = 1, 130 do
+ local code, body = t('/apisix/admin/routes/' .. i,
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello]] .. i .. [["
+ }]]
+ )
+ end
+
+ for i = 1, 130 do
+ local code, body = t('/apisix/admin/routes/' .. i,
+ ngx.HTTP_DELETE
+ )
+ end
+
+ ngx.say("done")
+ }
+ }
+--- request
+GET /t
+--- response_body
+done
+--- no_error_log
+[error]
+--- grep_error_log eval
+qr/\w+ (data by key: 126)/
+--- grep_error_log_out
+insert data by key: 126
+update data by key: 126
+delete data by key: 126
+insert data by key: 126
+delete data by key: 126
+--- timeout: 20