Incr/Decr Counters Using memcache-client

Posted 13 Aug 2011 to memcache, ruby and has Comments

Based on some recent changes in the memcached library, the incr method in the memcache-client gem no longer works as expected. For instance, the following:

require 'rubygems'
require 'memcache-client'

m = 'localhost'
m.set('counter', 0)

will result in the following error:

MemCache::MemCacheError: cannot increment or decrement non-numeric value
			 from /usr/lib/ruby/gems/1.8/gems/memcache-client-1.8.5/lib/memcache.rb:926:in `raise_on_error_response!'
			 from /usr/lib/ruby/gems/1.8/gems/memcache-client-1.8.5/lib/memcache.rb:831:in `cache_incr'
			 from /usr/lib/ruby/gems/1.8/gems/memcache-client-1.8.5/lib/memcache.rb:865:in `call'
			 from /usr/lib/ruby/gems/1.8/gems/memcache-client-1.8.5/lib/memcache.rb:865:in `with_socket_management'
			 from /usr/lib/ruby/gems/1.8/gems/memcache-client-1.8.5/lib/memcache.rb:827:in `cache_incr'
			 from /usr/lib/ruby/gems/1.8/gems/memcache-client-1.8.5/lib/memcache.rb:342:in `incr'
			 from /usr/lib/ruby/gems/1.8/gems/memcache-client-1.8.5/lib/memcache.rb:886:in `with_server'
			 from /usr/lib/ruby/gems/1.8/gems/memcache-client-1.8.5/lib/memcache.rb:341:in `incr'
			 from (irb):5
			 from /usr/local/lib/site_ruby/1.8/rubygems.rb:123

This is caused by the memcache-client gem marshalling everything before it’s stored in memcache. Memcache needs the actual, unmarshalled, integer value to be stored. The code above should be changed to:

require 'rubygems'
require 'memcache-client'

m = 'localhost'

# set the raw value initially by passing in a fourth argument of true
m.set('counter', 0, 0, true)

# increment the raw integer value

# you can now decrement the raw integer value as well

The fix is simple, but not noted anywhere (I can find it) in the memcache-client documentation. Besides a few mentions on Google-groups sans solution, I couldn’t find any references to this issue elsewhere on the world wide intertubes. I find the atomic incr/decr functionality in memcache to be quite useful; I hope this can help alleviate any issues others might be having with this problem.