Created
September 27, 2021 14:50
-
-
Save zhuizhuhaomeng/58ded3c18be560aa0225e31128d6f602 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/resty/memcached.lua b/lib/resty/memcached.lua | |
index bc2c496..41308a7 100644 | |
--- a/lib/resty/memcached.lua | |
+++ b/lib/resty/memcached.lua | |
@@ -7,6 +7,7 @@ local match = string.match | |
local tcp = ngx.socket.tcp | |
local strlen = string.len | |
local concat = table.concat | |
+local tab_insert = table.insert | |
local setmetatable = setmetatable | |
local type = type | |
@@ -23,8 +24,8 @@ if not ok or type(new_tab) ~= "function" then | |
new_tab = function (narr, nrec) return {} end | |
end | |
-local function _read_reply(sock, len) | |
- local line, err | |
+local function _read_reply(sock, len) | |
+ local line, err | |
if len == nil then | |
line, err = sock:receive() | |
else | |
@@ -200,7 +201,7 @@ local function _get_reply(sock) | |
return nil, nil, err | |
end | |
- line, err = _read_reply(sock, 7) -- discard the trailing "\r\nEND\r\n" | |
+ local _, err = _read_reply(sock, 7) -- discard the trailing "\r\nEND\r\n" | |
if err then | |
return nil, nil, err | |
end | |
@@ -218,14 +219,17 @@ function _M.get(self, key) | |
return nil, nil, "not initialized" | |
end | |
- local req = "get " .. self.escape_key(key) .. "\r\n" | |
local reqs = rawget(self, "_reqs") | |
if reqs then | |
- reqs[1][#reqs[1] + 1] = req | |
- reqs[2][#reqs[2] + 1] = _get_reply | |
+ local readers = rawget(self, "_readers") | |
+ tab_insert(reqs, "get ") | |
+ tab_insert(reqs, self.escape_key(key)) | |
+ tab_insert(reqs, "\r\n") | |
+ tab_insert(readers, _get_reply) | |
return 1 | |
end | |
+ local req = {"get ", self.escape_key(key), "\r\n"} | |
local bytes, err = sock:send(req) | |
if not bytes then | |
return nil, nil, err | |
@@ -312,7 +316,8 @@ function _M.gets(self, key) | |
return nil, nil, nil, "not initialized" | |
end | |
- local bytes, err = sock:send("gets " .. self.escape_key(key) .. "\r\n") | |
+ local req = {"gets ", self.escape_key(key), "\r\n"} | |
+ local bytes, err = sock:send(req) | |
if not bytes then | |
return nil, nil, nil, err | |
end | |
@@ -394,15 +399,27 @@ local function _store(self, cmd, key, value, exptime, flags) | |
value = _expand_table(value) | |
end | |
- local req = cmd .. " " .. self.escape_key(key) .. " " .. flags .. " " | |
- .. exptime .. " " .. strlen(value) .. "\r\n" .. value | |
- .. "\r\n" | |
local reqs = rawget(self, "_reqs") | |
if reqs then | |
- reqs[1][#reqs[1] + 1] = req | |
- reqs[2][#reqs[2] + 1] = _store_reply | |
+ local readers = rawget(self, "_readers") | |
+ tab_insert(reqs, cmd) | |
+ tab_insert(reqs, " ") | |
+ tab_insert(reqs, self.escape_key(key)) | |
+ tab_insert(reqs, " ") | |
+ tab_insert(reqs, flags) | |
+ tab_insert(reqs, " ") | |
+ tab_insert(reqs, exptime) | |
+ tab_insert(reqs, " ") | |
+ tab_insert(reqs, strlen(value)) | |
+ tab_insert(reqs, "\r\n") | |
+ tab_insert(reqs, value) | |
+ tab_insert(reqs, "\r\n") | |
+ | |
+ tab_insert(readers, _store_reply) | |
return 1 | |
end | |
+ local req = {cmd, " ", self.escape_key(key), " ", flags, " ", exptime, | |
+ " ", strlen(value), "\r\n", value, "\r\n"} | |
local bytes, err = sock:send(req) | |
if not bytes then | |
return nil, err | |
@@ -451,9 +468,8 @@ function _M.cas(self, key, value, cas_uniq, exptime, flags) | |
return nil, "not initialized" | |
end | |
- local req = "cas " .. self.escape_key(key) .. " " .. flags .. " " | |
- .. exptime .. " " .. strlen(value) .. " " .. cas_uniq | |
- .. "\r\n" .. value .. "\r\n" | |
+ local req = {"cas ", self.escape_key(key), " ", flags, " ", exptime, " ", | |
+ strlen(value), " ", cas_uniq, "\r\n", value, "\r\n"} | |
-- local cjson = require "cjson" | |
-- print("request: ", cjson.encode(req)) | |
@@ -498,14 +514,17 @@ function _M.delete(self, key) | |
key = self.escape_key(key) | |
- local req = "delete " .. key .. "\r\n" | |
local reqs = rawget(self, "_reqs") | |
if reqs then | |
- reqs[1][#reqs[1] + 1] = req | |
- reqs[2][#reqs[2] + 1] = _delete_reply | |
+ local readers = rawget(self, "_readers") | |
+ tab_insert(reqs, "delete ") | |
+ tab_insert(reqs, key) | |
+ tab_insert(reqs, "\r\n") | |
+ tab_insert(readers, _delete_reply) | |
return 1 | |
end | |
+ local req = {"delete ", key, "\r\n"} | |
local bytes, err = sock:send(req) | |
if not bytes then | |
return nil, err | |
@@ -543,7 +562,7 @@ function _M.flush_all(self, time) | |
local req | |
if time then | |
- req = "flush_all " .. time .. "\r\n" | |
+ req = {"flush_all ", time, "\r\n"} | |
else | |
req = "flush_all\r\n" | |
end | |
@@ -565,7 +584,7 @@ function _M.flush_all(self, time) | |
return 1 | |
end | |
-local function _incr_decr_reply(sock) | |
+local function _incr_decr_reply(sock) | |
local line, err = _read_reply(sock) | |
if err then | |
return nil, err | |
@@ -584,14 +603,20 @@ local function _incr_decr(self, cmd, key, value) | |
return nil, "not initialized" | |
end | |
- local req = cmd .. " " .. self.escape_key(key) .. " " .. value .. "\r\n" | |
local reqs = rawget(self, "_reqs") | |
+ local readers = rawget(self, "_readers") | |
if reqs then | |
- reqs[1][#reqs[1] + 1] = req | |
- reqs[2][#reqs[2] + 1] = _incr_decr_reply | |
+ tab_insert(reqs, cmd) | |
+ tab_insert(reqs, " ") | |
+ tab_insert(reqs, self.escape_key(key)) | |
+ tab_insert(reqs, " ") | |
+ tab_insert(reqs, value) | |
+ tab_insert(reqs, "\r\n") | |
+ tab_insert(readers, _incr_decr_reply) | |
return 1 | |
end | |
+ local req = {cmd," ", self.escape_key(key), " ", value, "\r\n"} | |
local bytes, err = sock:send(req) | |
if not bytes then | |
return nil, err | |
@@ -642,20 +667,27 @@ function _M.stats(self, args) | |
return nil, "not initialized" | |
end | |
- local req | |
- if args then | |
- req = "stats " .. args .. "\r\n" | |
- else | |
- req = "stats\r\n" | |
- end | |
- | |
local reqs = rawget(self, "_reqs") | |
+ local readers = rawget(self, "_readers") | |
if reqs then | |
- reqs[1][#reqs[1] + 1] = req | |
- reqs[2][#reqs[2] + 1] = _stats_reply | |
+ if args then | |
+ tab_insert(reqs, "stats ") | |
+ tab_insert(reqs, args) | |
+ tab_insert(reqs, "\r\n") | |
+ else | |
+ tab_insert(reqs, "stats\r\n") | |
+ end | |
+ tab_insert(readers, _stats_reply) | |
return 1 | |
end | |
+ | |
+ local req | |
+ if args then | |
+ req = {"stats ", args, "\r\n"} | |
+ else | |
+ req = "stats\r\n" | |
+ end | |
local bytes, err = sock:send(req) | |
if not bytes then | |
return nil, err | |
@@ -725,14 +757,17 @@ function _M.verbosity(self, level) | |
return nil, "not initialized" | |
end | |
- local req = "verbosity " .. level .. "\r\n" | |
local reqs = rawget(self, "_reqs") | |
if reqs then | |
- reqs[1][#reqs[1] + 1] = req | |
- reqs[2][#reqs[2] + 1] = _verbosity_reply | |
+ local readers = rawget(self, "_readers") | |
+ tab_insert(reqs, "verbosity ") | |
+ tab_insert(reqs, level) | |
+ tab_insert(reqs, "\r\n") | |
+ tab_insert(readers, _verbosity_reply) | |
return 1 | |
end | |
+ local req = {"verbosity ", level, "\r\n"} | |
local bytes, err = sock:send(req) | |
if not bytes then | |
return nil, err | |
@@ -760,14 +795,19 @@ function _M.touch(self, key, exptime) | |
return nil, "not initialized" | |
end | |
- local req = "touch " .. self.escape_key(key) .. " ".. exptime .. "\r\n" | |
local reqs = rawget(self, "_reqs") | |
+ local readers = rawget(self, "_readers") | |
if reqs then | |
- reqs[1][#reqs[1] + 1] = req | |
- reqs[2][#reqs[2] + 1] = _touch_reply | |
+ tab_insert(reqs, "touch ") | |
+ tab_insert(reqs, self.escape_key(key)) | |
+ tab_insert(reqs, " ") | |
+ tab_insert(reqs, exptime) | |
+ tab_insert(reqs, "\r\n") | |
+ tab_insert(readers, _touch_reply) | |
return 1 | |
end | |
+ local req = {"touch ", self.escape_key(key), " ", exptime, "\r\n"} | |
local bytes, err = sock:send(req) | |
if not bytes then | |
return nil, err | |
@@ -787,29 +827,29 @@ end | |
function _M.init_pipeline(self, n) | |
- if self._reqs then | |
+ if self._reqs then | |
return "already init pipeline" | |
end | |
if n and type(n) ~= 'number' then | |
- return "buffer size is number type" | |
+ return "bad n arg: number expected, but got " .. type(n) | |
end | |
- self._reqs = { | |
- new_tab(n or 4, 0), | |
- new_tab(n or 4, 0), | |
- } | |
+ self._reqs = new_tab(n or 20, 0) | |
+ self._readers = new_tab(n or 4, 0) | |
return nil | |
end | |
function _M.cancel_pipeline(self) | |
self._reqs = nil | |
+ self._readers = nil | |
end | |
function _M.commit_pipeline(self) | |
local reqs = rawget(self, "_reqs") | |
- if not reqs then | |
+ local readers = rawget(self, "_readers") | |
+ if not reqs or not readers then | |
return nil, "no pipeline" | |
end | |
local sock = self.sock | |
@@ -817,19 +857,20 @@ function _M.commit_pipeline(self) | |
return nil, "not initialized" | |
end | |
- if #self._reqs[1] == 0 then | |
+ if #self._reqs == 0 then | |
return nil, "no more cmds" | |
end | |
- local bytes, err = sock:send(concat(reqs[1])) | |
+ local bytes, err = sock:send(reqs) | |
if not bytes then | |
return nil, err | |
end | |
local results = {} | |
- for i=1, #reqs[2] do | |
- results[i] = { reqs[2][i](sock) } | |
+ for i=1, #readers do | |
+ results[i] = {readers[i](sock) } | |
end | |
self._reqs = nil | |
+ self._readers = nil | |
return results, nil | |
end | |
diff --git a/t/sanity.t b/t/sanity.t | |
index 136ae34..f4a456d 100644 | |
--- a/t/sanity.t | |
+++ b/t/sanity.t | |
@@ -1607,7 +1607,6 @@ failed to connect: timeout | |
lua tcp socket connect timed out | |
- | |
=== TEST 30: set keepalive and get reused times | |
--- http_config eval: $::HttpConfig | |
--- config | |
@@ -2470,6 +2469,6 @@ init: no pipeline | |
--- request | |
GET /t | |
--- response_body | |
-init: buffer size is number type | |
+init: bad n arg: number expected, but got string | |
--- no_error_log | |
[error] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment