From e178edd2982cf6793fdb2303ae77304aa13ebff5 Mon Sep 17 00:00:00 2001 From: wangyuansheng Date: Fri, 4 Dec 2015 14:20:16 +0800 Subject: [PATCH 1/8] keep the key never overrides never overrides the (least recently used) unexpired items in the store when running out of storage in the shared memory zone --- lib/resty/lock.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/resty/lock.lua b/lib/resty/lock.lua index cf305cb..cd9a7a8 100644 --- a/lib/resty/lock.lua +++ b/lib/resty/lock.lua @@ -128,7 +128,7 @@ function _M.lock(self, key) return nil, "locked" end local exptime = self.exptime - local ok, err = dict:add(key, true, exptime) + local ok, err = dict:safe_add(key, true, exptime) if ok then cdata.key_id = ref_obj(key) if not shdict_mt then @@ -154,7 +154,7 @@ function _M.lock(self, key) elapsed = elapsed + step timeout = timeout - step - local ok, err = dict:add(key, true, exptime) + local ok, err = dict:safe_add(key, true, exptime) if ok then cdata.key_id = ref_obj(key) if not shdict_mt then From 61760d613c0d70cf657b38e6a6053d0bfb64ccae Mon Sep 17 00:00:00 2001 From: YuanSheng Wang Date: Sun, 6 Dec 2015 10:35:48 +0800 Subject: [PATCH 2/8] add an option for safe_add its more strictness for some special case --- lib/resty/lock.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/resty/lock.lua b/lib/resty/lock.lua index cd9a7a8..50809a7 100644 --- a/lib/resty/lock.lua +++ b/lib/resty/lock.lua @@ -94,6 +94,7 @@ function _M.new(_, dict_name, opts) step = opts.step ratio = opts.ratio max_step = opts.max_step + save_add = opts.save_add end if not exptime then @@ -107,6 +108,7 @@ function _M.new(_, dict_name, opts) local self = { cdata = cdata, dict = dict, + dict_add = save_add and dict.save_add or dict.add, timeout = timeout or 5, exptime = exptime, step = step or 0.001, @@ -128,7 +130,7 @@ function _M.lock(self, key) return nil, "locked" end local exptime = self.exptime - local ok, err = dict:safe_add(key, true, exptime) + local ok, err = self.dict_add(dict, key, true, exptime) if ok then cdata.key_id = ref_obj(key) if not shdict_mt then @@ -154,7 +156,7 @@ function _M.lock(self, key) elapsed = elapsed + step timeout = timeout - step - local ok, err = dict:safe_add(key, true, exptime) + local ok, err = self.dict_add(dict, key, true, exptime) if ok then cdata.key_id = ref_obj(key) if not shdict_mt then From 19d48da8d5e942b2ea7b1a26b7d58d23aa8d86a4 Mon Sep 17 00:00:00 2001 From: YuanSheng Wang Date: Sun, 6 Dec 2015 11:19:58 +0800 Subject: [PATCH 3/8] fix the typos add the test case #14: serial lock and unlock with safe_add --- lib/resty/lock.lua | 4 ++-- t/sanity.t | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/resty/lock.lua b/lib/resty/lock.lua index 50809a7..36a58fc 100644 --- a/lib/resty/lock.lua +++ b/lib/resty/lock.lua @@ -94,7 +94,7 @@ function _M.new(_, dict_name, opts) step = opts.step ratio = opts.ratio max_step = opts.max_step - save_add = opts.save_add + safe_add = opts.safe_add end if not exptime then @@ -108,7 +108,7 @@ function _M.new(_, dict_name, opts) local self = { cdata = cdata, dict = dict, - dict_add = save_add and dict.save_add or dict.add, + dict_add = safe_add and dict.safe_add or dict.add, timeout = timeout or 5, exptime = exptime, step = step or 0.001, diff --git a/t/sanity.t b/t/sanity.t index b04497c..7885917 100644 --- a/t/sanity.t +++ b/t/sanity.t @@ -468,3 +468,34 @@ lock 2: unlock: nil, unlocked --- no_error_log [error] + + +=== TEST 14: serial lock and unlock with safe_add +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua ' + local lock = require "resty.lock" + for i = 1, 2 do + local lock = lock:new("cache_locks", {safe_add = true}) + local elapsed, err = lock:lock("foo") + ngx.say("lock: ", elapsed, ", ", err) + local ok, err = lock:unlock() + if not ok then + ngx.say("failed to unlock: ", err) + end + ngx.say("unlock: ", ok) + end + '; + } +--- request +GET /t +--- response_body +lock: 0, nil +unlock: 1 +lock: 0, nil +unlock: 1 + +--- no_error_log +[error] + From f9883111269d535b1e0f50b1fff5f0c3458bf26d Mon Sep 17 00:00:00 2001 From: YuanSheng Wang Date: Sun, 6 Dec 2015 13:43:38 +0800 Subject: [PATCH 4/8] add test case use safe_add, dont have enough memory --- t/sanity.t | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/t/sanity.t b/t/sanity.t index 7885917..0a1ff73 100644 --- a/t/sanity.t +++ b/t/sanity.t @@ -499,3 +499,45 @@ unlock: 1 --- no_error_log [error] + + +=== TEST 15: use safe_add, dont have enough memory +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua ' + local lock = require "resty.lock" + local cache = ngx.shared.cache_locks + + cache:flush_all() + function full_dict( dict ) + for i=1,10000 do + local ok, err = dict:safe_set(string.rep("2", 2)..i, string.rep("2", 5)..i) + if not ok then + return + end + end + end + full_dict(cache) + + + local lock1 = lock:new("cache_locks", {safe_add = true, timeout = 0}) + local elapsed, err = lock1:lock("foo") + ngx.say("lock: ", elapsed, ", ", err) + + local lock2 = lock:new("cache_locks", {timeout = 0}) + local elapsed, err = lock2:lock("foo") + ngx.say("lock: ", elapsed, ", ", err) + '; + } +--- request +GET /t +--- response_body +lock: nil, no memory +lock: 0, nil + +--- no_error_log +[error] + + + From 2665d2a90cd774ef8b8d8a040db668623e07c111 Mon Sep 17 00:00:00 2001 From: wangyuansheng Date: Mon, 7 Dec 2015 09:51:19 +0800 Subject: [PATCH 5/8] modify the format modify the format for the source and test case. --- lib/resty/lock.lua | 5 +++-- t/sanity.t | 15 ++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/resty/lock.lua b/lib/resty/lock.lua index 36a58fc..8a9b083 100644 --- a/lib/resty/lock.lua +++ b/lib/resty/lock.lua @@ -130,7 +130,8 @@ function _M.lock(self, key) return nil, "locked" end local exptime = self.exptime - local ok, err = self.dict_add(dict, key, true, exptime) + local dict_add = self.dict_add + local ok, err = dict_add(dict, key, true, exptime) if ok then cdata.key_id = ref_obj(key) if not shdict_mt then @@ -156,7 +157,7 @@ function _M.lock(self, key) elapsed = elapsed + step timeout = timeout - step - local ok, err = self.dict_add(dict, key, true, exptime) + local ok, err = dict_add(dict, key, true, exptime) if ok then cdata.key_id = ref_obj(key) if not shdict_mt then diff --git a/t/sanity.t b/t/sanity.t index 0a1ff73..2783eba 100644 --- a/t/sanity.t +++ b/t/sanity.t @@ -511,8 +511,8 @@ unlock: 1 cache:flush_all() function full_dict( dict ) - for i=1,10000 do - local ok, err = dict:safe_set(string.rep("2", 2)..i, string.rep("2", 5)..i) + for i = 1, 10000 do + local ok, err = dict:safe_set(string.rep("2", 2) .. i, string.rep("2", 5) .. i) if not ok then return end @@ -520,24 +520,21 @@ unlock: 1 end full_dict(cache) - local lock1 = lock:new("cache_locks", {safe_add = true, timeout = 0}) local elapsed, err = lock1:lock("foo") - ngx.say("lock: ", elapsed, ", ", err) + ngx.say("lock1: ", elapsed, ", ", err) local lock2 = lock:new("cache_locks", {timeout = 0}) local elapsed, err = lock2:lock("foo") - ngx.say("lock: ", elapsed, ", ", err) + ngx.say("lock2: ", elapsed, ", ", err) '; } --- request GET /t --- response_body -lock: nil, no memory -lock: 0, nil +lock1: nil, no memory +lock2: 0, nil --- no_error_log [error] - - From 3a390831d152f3d6d1f536fb6fa107fb6faf7dfc Mon Sep 17 00:00:00 2001 From: wangyuansheng Date: Mon, 7 Dec 2015 15:07:22 +0800 Subject: [PATCH 6/8] add another two test cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit three case: use the safe_add to “true” , “false” or default, confirm it’ll work correct. --- t/sanity.t | 81 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/t/sanity.t b/t/sanity.t index 2783eba..4d04868 100644 --- a/t/sanity.t +++ b/t/sanity.t @@ -501,7 +501,7 @@ unlock: 1 -=== TEST 15: use safe_add, dont have enough memory +=== TEST 15: use safe_add = true, dont have enough memory --- http_config eval: $::HttpConfig --- config location = /t { @@ -520,20 +520,83 @@ unlock: 1 end full_dict(cache) - local lock1 = lock:new("cache_locks", {safe_add = true, timeout = 0}) - local elapsed, err = lock1:lock("foo") - ngx.say("lock1: ", elapsed, ", ", err) + local lock = lock:new("cache_locks", {safe_add = true, timeout = 0}) + local elapsed, err = lock:lock("foo") + ngx.say("lock: ", elapsed, ", ", err) + '; + } +--- request +GET /t +--- response_body +lock: nil, no memory + +--- no_error_log +[error] + + + +=== TEST 16: use safe_add = false, dont have enough memory +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua ' + local lock = require "resty.lock" + local cache = ngx.shared.cache_locks - local lock2 = lock:new("cache_locks", {timeout = 0}) - local elapsed, err = lock2:lock("foo") - ngx.say("lock2: ", elapsed, ", ", err) + cache:flush_all() + function full_dict( dict ) + for i = 1, 10000 do + local ok, err = dict:safe_set(string.rep("2", 2) .. i, string.rep("2", 5) .. i) + if not ok then + return + end + end + end + full_dict(cache) + + local lock = lock:new("cache_locks", {safe_add = false, timeout = 0}) + local elapsed, err = lock:lock("foo") + ngx.say("lock: ", elapsed, ", ", err) '; } --- request GET /t --- response_body -lock1: nil, no memory -lock2: 0, nil +lock: 0, nil + +--- no_error_log +[error] + + + +=== TEST 17: use safe_add by default, dont have enough memory +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua ' + local lock = require "resty.lock" + local cache = ngx.shared.cache_locks + + cache:flush_all() + function full_dict( dict ) + for i = 1, 10000 do + local ok, err = dict:safe_set(string.rep("2", 2) .. i, string.rep("2", 5) .. i) + if not ok then + return + end + end + end + full_dict(cache) + + local lock = lock:new("cache_locks", {timeout = 0}) + local elapsed, err = lock:lock("foo") + ngx.say("lock: ", elapsed, ", ", err) + '; + } +--- request +GET /t +--- response_body +lock: 0, nil --- no_error_log [error] From 96640dbf69bcdca9108d99a5924262210917e923 Mon Sep 17 00:00:00 2001 From: wangyuansheng Date: Mon, 7 Dec 2015 16:04:23 +0800 Subject: [PATCH 7/8] change the test case title --- t/sanity.t | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/t/sanity.t b/t/sanity.t index 4d04868..97be7b7 100644 --- a/t/sanity.t +++ b/t/sanity.t @@ -501,7 +501,7 @@ unlock: 1 -=== TEST 15: use safe_add = true, dont have enough memory +=== TEST 15: the "safe_add" option is true: exhausting the shm zone memory --- http_config eval: $::HttpConfig --- config location = /t { @@ -535,7 +535,7 @@ lock: nil, no memory -=== TEST 16: use safe_add = false, dont have enough memory +=== TEST 16: the "safe_add" option is false: exhausting the shm zone memory --- http_config eval: $::HttpConfig --- config location = /t { @@ -569,7 +569,7 @@ lock: 0, nil -=== TEST 17: use safe_add by default, dont have enough memory +=== TEST 17: the "safe_add" option is off by default: exhausting the shm zone memory --- http_config eval: $::HttpConfig --- config location = /t { From 35893141764ed1171dacdf113c0f48cf8e92cbf2 Mon Sep 17 00:00:00 2001 From: wangyuansheng Date: Mon, 14 Dec 2015 19:09:45 +0800 Subject: [PATCH 8/8] declare the variable at first --- lib/resty/lock.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resty/lock.lua b/lib/resty/lock.lua index 8a9b083..0187c30 100644 --- a/lib/resty/lock.lua +++ b/lib/resty/lock.lua @@ -87,7 +87,7 @@ function _M.new(_, dict_name, opts) cdata.key_id = 0 cdata.dict_id = ref_obj(dict) - local timeout, exptime, step, ratio, max_step + local timeout, exptime, step, ratio, max_step, safe_add if opts then timeout = opts.timeout exptime = opts.exptime