em-redis icon indicating copy to clipboard operation
em-redis copied to clipboard

setnx listed as a bulk command, should it be?

Open impact11 opened this issue 13 years ago • 1 comments

According to Redis documentation, setnx takes only two parameters (key and value). Within redis_protocol.rb, setnx is listed as a bulk command. This seems to cause the send_command() function to append the length of the last argument passed into the function to the command sequence, which causes a Redis error.

Example: The Ohm library calls

 key[:_lock].setnx(Time.now.to_f + 0.5)

The send_command() function receives a 3-element array:

 argv = [ "setnx", "OhmClassName:132:_lock", "1314673377.348075"]

Because setnx is listed in BULK_COMMAND array at header of redis_protocol.rb, send_command() takes the length of "1314673377.348075" and inserts it into the command list as if it were the value for the command, like so:

 setnx OhmClassName:132:_lock 17 1314673377.348075

This results in an error

:1 -ERR unknown command '1314673377.348075' 

because redis interprets the inserted length (17) as the value, and treats the timestamp that follows as if it were a command.

Changing BULK_COMMAND to make setnx to false seems to rectify this behavior, but this is happening with other Redis commands listed in there that only take two parameters (e.g. 'set', 'sismember', etc). Even for those that take multiple arguments (e.g. sadd) it seems unusual to add the length of the remainder into the command, rather than just appending the remaining arguments.

What is the logic behind the BULK_COMMAND array and the thought behind what commands are listed there, and that block in send_command()? Is there something I am missing?

(Thanks greatly for having made this in the first place, btw!)

impact11 avatar Aug 30 '11 03:08 impact11

Unified request protocol #7

portertech avatar Jan 07 '13 17:01 portertech