Skip to content

Instantly share code, notes, and snippets.

@zhuizhuhaomeng
Created September 27, 2021 14:50
Show Gist options
  • Save zhuizhuhaomeng/58ded3c18be560aa0225e31128d6f602 to your computer and use it in GitHub Desktop.
Save zhuizhuhaomeng/58ded3c18be560aa0225e31128d6f602 to your computer and use it in GitHub Desktop.
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