Caching is great and memcache, despite other alternatives being available, is still great too. You can accelerate and app, shard your data, whatever.

It’s a black box in a way, though, too. It can be difficult in a production or pre-production environment whether or not your cache is actually being used. I had that problem today and having never used memcached under Rails before (perl, yes) I wanted to be sure that things were happening under the covers the way I wanted them to.

Testing that your app is writing to the cache is easy. Memcache doesn’t believe in binary protocols, it uses text and you so you can communicate with it in text. The memcache server itself will respond to command you give it from a raw socket or even telnet. Simply telnet into the servers’ bound IP and port:
# telnet localhost 11211
And you should be given nothing but a blank prompt. But from there you can do basic commands like
stats
Which will print you out some basic stats. Their details are better discussed in better blogs so I won’t bother here. What I’m more interested in is seeing if the data I want to be written IS being written.

So, I find the cache key Rails is using in a place like this for example:

Rails.cache.write('Some_Key_23', value, :expires => 1.hour)
..and I enter that key name into the telnet prompt I have open to my memcached server
get Some_Key_23
If that key is NOT on the server all I get back is “END”, but if there is data written to that I will get something more like
VALUE Some_Key_23 0 8
Hello!
END

If I wanted to delete that key I could then issue
delete Some_Key_23
And the value would be deleted and I could check if it gets recreated again with the ‘get’ command.

I can even WRITE data to a key with telnet, but NOTE, it’s pretty hard to do by hand because the Rails default cache handler is going to write data to the cache as a data object (e.g. a String, Hash, Array, etc) and you’d have to write hex to the terminal to get the same effect. Not fun.

Instead, I wrote up a small rails command line app to handle it for me called ‘memcacher’:

#!/usr/bin/env ruby
require 'rubygems'
require 'trollop'

opts = Trollop.options do
opt :key, "key name", :type => :string, :required => true
opt :write, "data to write to key", :type => :string, :required => false
opt :environment, "Rails Environment", :default => "development", :type => :string
opt :inspect, "read data with .inspect or write with eval {}", :default => false, :type => :boolean
end

RAILS_ENV = opts[:environment]
require File.dirname(__FILE__) + '/../config/environment'

if opts[:write]
if opts[:inspect]
Rails.cache.write(opts[:key], eval(opts[:write]), :expires => 1.hour)
else
Rails.cache.write(opts[:key], opts[:write], :expires => 1.hour)
end
else
if opts[:inspect]
puts Rails.cache.read(opts[:key]).inspect
else
puts Rails.cache.read(opts[:key])
end
end


This way I can use a more sensible tool to read data, see what type it is or even WRITE it.
# memcacher -k Some_Key_23
Hello!
# memcacher -k Some_Key_23 -i
“Hello!”
# memcacher -k Some_Array_23 -i
["Hey there!"]
# memcacher -k Some_Array_23 -i -w “[['Yo Dawg'], ['I heard you like arrays'], ['so we put arrays in your arrays']]”
# memcacher -k Some_Array_23 -i
[["Yo Dawg"], ["I heard you like arrays"], ["so we put arrays in your arrays"]]

So, what good is it to be able to change the contents of a cached object? Well, if you want to do some visual testing on your caching you can wait for a cache key to be generated, redefine it with your new data and reload the page to see: if the data you manually write to the cache gets displayed you know your app is caching properly, otherwise it’s not and the data is being pulled from somewhere else.