Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix crashing when multi/exec is used during pipelining.

  • Loading branch information...
commit 2a80cb8eae315a6c42538f8e87177da8b6cc331a 1 parent 1baf835
@silentbicycle authored
Showing with 41 additions and 7 deletions.
  1. +18 −7 sidereal.lua
  2. +23 −0 test.lua
View
25 sidereal.lua
@@ -130,10 +130,23 @@ function Sidereal:pass()
end
+local function pipeline_cmd(self, cmd)
+ trace("PIPELINED:", cmd)
+ local p = self._pipeline
+ p[#p+1] = cmd
+ self._pipeline_ct = self._pipeline_ct + 1
+ return true, PIPELINED
+end
+
+
---Send a raw string, don't wait for response.
-function Sidereal:send(cmd, retry)
+function Sidereal:send(cmd, retry, is_pipeline)
local pass = self.pass
+ if self._pipeline and not is_pipeline then
+ return pipeline_cmd(self, cmd)
+ end
+
while true do
local ok, err = self._socket:send(cmd .. "\r\n")
if ok then
@@ -167,11 +180,7 @@ local _get_response
---Send a raw string and (if not pipelining) return the response.
function Sidereal:send_receive(cmd, retry)
if self._pipeline then
- trace("PIPELINED:", cmd)
- local p = self._pipeline
- p[#p+1] = cmd
- self._pipeline_ct = self._pipeline_ct + 1
- return true, PIPELINED
+ return pipeline_cmd(self, cmd)
else
local ok, err, rest = self:send(cmd, retry)
if not ok then return nil, err end
@@ -231,7 +240,8 @@ end
-- commands remain in the pipeline. Be sure to check send_pipeline's result!
function Sidereal:send_pipeline()
if not self._pipeline then return nil, "Not pipelining" end
- local ok, err = self:send(concat(self._pipeline, "\r\n"))
+ trace("SENDING PIPELINE", self._pipeline_ct)
+ local ok, err = self:send(concat(self._pipeline, "\r\n"), nil, true)
if ok then
self._pipeline = false
else
@@ -1056,6 +1066,7 @@ function Sidereal:exec() end
cmd("EXEC", nil, { noreply=true,
post_hook = --collect multiple results
function(self)
+ if self._pipeline then return end
local ok, line = self:receive("*l")
if not ok then error("handling multiple responses failed(1)") end
local ct = line:match("%*(%d+)")
View
23 test.lua
@@ -2297,6 +2297,29 @@ function test_SDIFF_MULTI_EXEC()
cmp(x[1], {"one", "three"})
end
+function test_pipeline_MULTI()
+ R:set("MYKEY", "value")
+ R:pipeline()
+ R:multi()
+ R:get("MYKEY")
+ R:exec()
+ R:send_pipeline()
+
+ local ok, res = R:get_response()
+ assert(ok)
+ assert_equal("OK", res)
+
+ ok, res = R:get_response()
+ assert(ok)
+ assert_equal("QUEUED", res)
+
+ ok, res = R:get_response()
+ assert(ok)
+ assert_table(res)
+ assert_equal("value", res[1])
+
+end
+
if do_reconnect then
-- Set your Redis timeout to less than the usual 300 for this one!
Please sign in to comment.
Something went wrong with that request. Please try again.