stephenmcd / curiodb

Distributed NoSQL Database
http://curiodb.jupo.org
BSD 2-Clause "Simplified" License
511 stars 47 forks source link

MSETNX behaves wrong #6

Closed tramchamploo closed 9 years ago

tramchamploo commented 9 years ago

127.0.0.1:6379> get a (nil) 127.0.0.1:6379> get b (nil) 127.0.0.1:6379> get c (nil) 127.0.0.1:6379> set b b OK 127.0.0.1:6379> msetnx a a b b c c (integer) 1 127.0.0.1:6379> get a "a" 127.0.0.1:6379> get b "b" 127.0.0.1:6379> get c "c"

The reason is AggregateMSetNX extends AggregateBroadcast which overrides begin method, it just check Command's first key. So if I set the second key already, it doesn't validate existence right. So is it really necessary to broadcast to all KeyNodes for behaviors like MSETNX? Also is there a plan to write some test cases?

stephenmcd commented 9 years ago

The idea with using broadcast is that it optimizes for a large number of keys. If we didn't use broadcast, we would have to run EXISTS for every individual key, which would mean num messages == num keys. Instead we broadcast all keys to all KeyNodes - so num messages == num keynodes. Since each KeyNode then gets all keys, some which don't map to it, they should just return false values in their responses for each of the keys that don't map to them, which is fine - so long as we get back true values for the keys that do exist, from the KeyNodes they belong to.

Having said all that, I can see the bug, but I don't think it's due to using broadcast, which is the intention here - need to keep on digging, let's see who finds it first.

Also yes, we definitely need tests! I wonder if we can somehow leverage an existing set of tests for Redis? I tried using the TCL tests for Redis itself, but I couldn't get them to run against an external server, and they're probably too exhaustive anyway. Can you think of any other spots we mind find a good set of general Redis tests?

stephenmcd commented 9 years ago

Ok I found the bug - it was as simple as the wrong method name being overridden in AggregateMSetNX - it should have been broadcastArgs instead of keys. Basically if you study AggregateBroadcast (which AggregateMSetNX eventually extends), you'll see it takes over the keys method with an integer range (one per KeyNode, since it's communicating with all of them), and then uses its own broadcastArgs to implement command args (or keys).

I also updated the comments to try and explain this more clearly. Thanks again for the report! Looking forward to the next bug. :-)

stephenmcd commented 9 years ago

Fixed in 3a53d78bb1a2e658d53f1e587c877d4e6076ae4f

tramchamploo commented 9 years ago

What about tests for a java or scala redis client?

stephenmcd commented 9 years ago

Great idea On 10/07/2015 12:32 PM, "tramchamploo" notifications@github.com wrote:

What about tests for a java or scala redis client?

— Reply to this email directly or view it on GitHub https://github.com/stephenmcd/curiodb/issues/6#issuecomment-120205668.