diff --git a/apisix/plugins/limit-conn/limit-conn-redis-cluster.lua b/apisix/plugins/limit-conn/limit-conn-redis-cluster.lua index 9295238724b3..9e46a04b2181 100644 --- a/apisix/plugins/limit-conn/limit-conn-redis-cluster.lua +++ b/apisix/plugins/limit-conn/limit-conn-redis-cluster.lua @@ -16,10 +16,8 @@ -- local redis_cluster = require("apisix.utils.rediscluster") local core = require("apisix.core") -local assert = assert +local util = require("apisix.plugins.limit-conn.util") local setmetatable = setmetatable -local math = require "math" -local floor = math.floor local ngx_timer_at = ngx.timer.at local _M = {version = 0.1} @@ -49,44 +47,7 @@ end function _M.incoming(self, key, commit) - local max = self.max - local red = self.red_cli - - self.committed = false - - local hash_key = "limit_conn" - - local conn, err - if commit then - conn, err = red:hincrby(hash_key, key, 1) - if not conn then - return nil, err - end - - if conn > max + self.burst then - conn, err = red:hincrby(hash_key, key, -1) - if not conn then - return nil, err - end - return nil, "rejected" - end - self.committed = true - - else - local conn_from_red, err = red:hget(hash_key, key) - if err then - return nil, err - end - conn = (conn_from_red or 0) + 1 - end - - if conn > max then - -- make the excessive connections wait - return self.unit_delay * floor((conn - 1) / max), conn - end - - -- we return a 0 delay by default - return 0, conn + return util.incoming(self, self.red_cli, key, commit) end @@ -96,28 +57,11 @@ end local function leaving_thread(premature, self, key, req_latency) - - local red = self.red_cli - - local hash_key = "limit_conn" - - local conn, err = red:hincrby(hash_key, key, -1) - if not conn then - return nil, err - end - - if req_latency then - local unit_delay = self.unit_delay - self.unit_delay = (req_latency + unit_delay) / 2 - end - - return conn + return util.leaving(self, self.red_cli, key, req_latency) end function _M.leaving(self, key, req_latency) - assert(key) - -- log_by_lua can't use cosocket local ok, err = ngx_timer_at(0, leaving_thread, self, key, req_latency) if not ok then diff --git a/apisix/plugins/limit-conn/limit-conn-redis.lua b/apisix/plugins/limit-conn/limit-conn-redis.lua index e8a3861d7529..4de7a27fdca2 100644 --- a/apisix/plugins/limit-conn/limit-conn-redis.lua +++ b/apisix/plugins/limit-conn/limit-conn-redis.lua @@ -14,11 +14,9 @@ -- See the License for the specific language governing permissions and -- limitations under the License. -- -local redis = require("apisix.utils.redis") +local redis = require("apisix.utils.redis") local core = require("apisix.core") -local assert = assert -local math = require "math" -local floor = math.floor +local util = require("apisix.plugins.limit-conn.util") local ngx_timer_at = ngx.timer.at local setmetatable = setmetatable @@ -45,49 +43,12 @@ end function _M.incoming(self, key, commit) - local max = self.max - local conf = self.conf local red, err = redis.new(conf) if not red then return red, err end - - self.committed = false - - local hash_key = "limit_conn" - - local conn, err - if commit then - conn, err = red:hincrby(hash_key, key, 1) - if not conn then - return nil, err - end - - if conn > max + self.burst then - conn, err = red:hincrby(hash_key, key, -1) - if not conn then - return nil, err - end - return nil, "rejected" - end - self.committed = true - - else - local conn_from_red, err = red:hget(hash_key, key) - if err then - return nil, err - end - conn = (conn_from_red or 0) + 1 - end - - if conn > max then - -- make the excessive connections wait - return self.unit_delay * floor((conn - 1) / max), conn - end - - -- we return a 0 delay by default - return 0, conn + return util.incoming(self, red, key, commit) end @@ -103,26 +64,11 @@ local function leaving_thread(premature, self, key, req_latency) if not red then return red, err end - - local hash_key = "limit_conn" - - local conn, err = red:hincrby(hash_key, key, -1) - if not conn then - return nil, err - end - - if req_latency then - local unit_delay = self.unit_delay - self.unit_delay = (req_latency + unit_delay) / 2 - end - - return conn + return util.leaving(self, red, key, req_latency) end function _M.leaving(self, key, req_latency) - assert(key) - -- log_by_lua can't use cosocket local ok, err = ngx_timer_at(0, leaving_thread, self, key, req_latency) if not ok then diff --git a/apisix/plugins/limit-conn/util.lua b/apisix/plugins/limit-conn/util.lua new file mode 100644 index 000000000000..0142482ba09e --- /dev/null +++ b/apisix/plugins/limit-conn/util.lua @@ -0,0 +1,84 @@ +-- +-- 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 core = require("apisix.core") + +local assert = assert +local math = require "math" +local floor = math.floor +local _M = {version = 0.3} + + +function _M.incoming(self, red, key, commit) + local max = self.max + self.committed = false + local hash_key = "limit_conn" + + local conn, err + if commit then + conn, err = red:hincrby(hash_key, key, 1) + if not conn then + return nil, err + end + + if conn > max + self.burst then + conn, err = red:hincrby(hash_key, key, -1) + if not conn then + return nil, err + end + return nil, "rejected" + end + self.committed = true + + else + local conn_from_red, err = red:hget(hash_key, key) + if err then + return nil, err + end + conn = (conn_from_red or 0) + 1 + end + + if conn > max then + -- make the excessive connections wait + return self.unit_delay * floor((conn - 1) / max), conn + end + + -- we return a 0 delay by default + return 0, conn +end + + + +function _M.leaving(self, red, key, req_latency) + assert(key) + local hash_key = "limit_conn" + + local conn, err = red:hincrby(hash_key, key, -1) + if not conn then + return nil, err + end + + if req_latency then + local unit_delay = self.unit_delay + self.unit_delay = (req_latency + unit_delay) / 2 + end + + return conn +end + + +return _M