Ruby memcache-client enhancement

Recently I have been refactoring some code so that various computed results are saved in a memcached cache to improve performance.

A common cache idiom is:

  1. Compute cache key
  2. look up key in cache
  3. if value found, return it
  4. else, run some code to generate the required value
  5. save the generated value in the cache
  6. return the value

It's quite awkward to have that code repeated all over your app, so I hit upon the idea of passing a block to Cache#get() which would be used to compute the value if the key wasn't found in the cache.

My proof of concept code to add this functionality to the Cache module is:

module Cache
  class << self
    alias _get get
  end

  def self.get(key, expiry = 0)
    value = _get(key)
    if value.nil? && block_given?
      value = yield
      put(key, value, expiry)
    end
    value
  end
end

If no block is given, it works exactly the same as the original get() method. If a block is given then the block is executed to generate the value if it isn't found in the cache. The value is then stored in the cache and returned.

My code looks nicer now, instead of this:

cache_key = "#{some}/#{vars}"
value = Cache.get cache_key
unless value
  value = a_SOAP_call_that_takes_a_few_seconds()
  Cache.put cache_key, value, 10.minutes
end
value

I now have this:

Cache.get("#{some}/#{vars}", 10.minutes) do
  a_SOAP_call_that_takes_a_few_seconds()
end

I have logged this possible enhancement to the bug tracker for memcache-client.

This entry was posted on Wed, 23 Aug 2006 07:26:57 GMT . You can follow any any response to this entry through the Atom feed. You can leave a comment or a trackback from your own site.
Tags ,


Trackbacks

Use the following link to trackback from your own site:
http://evansweb.info/trackbacks?article_id=ruby-memcache-client-enhancement&day=23&month=08&year=2006

Comments

Leave a response

  1. Avatar
    Yan 22 days later:

    you should maybe enhance it with some DSL magic to make the syntax something like

    cache “#{some}/#{vars}”, 10.minutes do … end

    No reason to have that ugly Cache.get everywhere :)

  2. Avatar
    Jon Evans 22 days later:

    @Yan: that’s a great idea… looking into it now.

Leave a comment