Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi doesn't handle responses properly #561

Closed
fcheung opened this issue Sep 22, 2015 · 2 comments
Closed

multi doesn't handle responses properly #561

fcheung opened this issue Sep 22, 2015 · 2 comments

Comments

@fcheung
Copy link

fcheung commented Sep 22, 2015

Dalli's multi method doesn't seem to handle responses as it should. The following snippet demonstrates the problem I've observed

dalli.set('foo', 'bar')
dalli.multi { dalli.delete 'keythatdoesnotexist'}
dalli.get 'foo' #=> returns true !
dalli.get 'foo' #=> returns 'bar' as expected

I'm not very familiar with the memcached protocol, and it's not really described in the protocol docs (other than in the getq) case, but it sounds:

  • quiet ops suppress non interesting responses
  • quiet ops delay starting to send a response until a non quiet response is sent.

Since this isn't happening in the above, the interesting responses from the dalli.multi block only get sent when the get request is made & dalli ends up returning the response from the failed delete as the get request.

Ideally (for me at least). multi would take care of this by sending a noop request and reading any response data, but this would mean that all existing uses of multi would incur one extra request. At the very least this should be called out in the docs, ideally with the addition of a read_responses option to multi.

The noop method on Server nearly does the right thing, although it assumes that all response are KV responses whereas they could be of any type (in addition this functionality isn't exposed on Client).

Happy to work on this if a direction is agreed.

@moxley
Copy link

moxley commented Nov 13, 2015

I'm getting similar results:

dalli.set('foo', 'bar')
dalli.multi { dalli.delete 'keythatdoesnotexist'}
dalli.get 'foo' #=> returns nil. should have been 'bar'
dalli.get 'foo' #=> returns 'bar' as expected

dalli.set('foo', 'bar')
dalli.multi { dalli.delete 'keythatdoesnotexist'}
dalli.get 'foo' #=> returns true, should have been 'bar'
dalli.get 'foo' #=> returns nil, should have been 'bar'

dalli.set('foo', 'bar')
dalli.multi { dalli.delete 'keythatdoesnotexist'}
dalli.get 'foo' #=> returns "bar"
dalli.get 'foo' #=> returns 'bar'

@kamaljoshi
Copy link

This seems to be related to this: #321

It seems the response is available with the socket but because the multi command doesn't end up reading it. It gets read with the next request according to bin protocol and only the response to the last request is returned.

dalli.set('foo', 'bar')
dalli.multi { dalli.delete 'keythatdoesnotexist'}
dalli.send(:ring).servers.each {|server| p server.sock.read_available} #=> "\x81\x14\x00\x00\x00\x00\x00\x01\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Not found"

It kind of makes multi unusable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants