Utilizing Caches.rb with Ferret

We needed to cache a Ruby class method calling the Ferret indexing engine.
“Yurii Rashkovskii”:http://rashkovskii.com/tags/caches developed a great library called “Caches.rb”:http://pad.verbdev.com/cachesrb/.

When I googled it out, it seemed very simple to use and promised to do *EXACTLY* what I need (even the default timeout was *JUST IT*). I especially liked the very Rails-like tutorial “Don’t tell, show me!”:http://pad.verbdev.com/cachesrb/. However, it required quite some effort to make it work, mainly because of the rather sparse documentation. Still, in the end the usage is very elegant, the solution is simple and it does what it promises. Thank you, Yurii!

To help our esteemed readers get faster over that less agreeable middle phase, here are a few tips:

* *Downloading it*: I tried gems but the gem list server seemed to be overloaded, and when it worked at last, I just got an older version (0.2.0). When checking out (or exporting) version 0.4.0 from SVN trunk directly, the trick was in finding out the latest working SVN URL:

@ruby script/plugin install http://svn.verbdev.com/rb/caches.rb/trunk@
* With all the typical Rails mixin stuff petrified in my mind, it took me a while to notice that caching should be declared *AFTER* the definition of the method to be cached, and not at the beginning of the class definition.
The example in the documentation shows it, but it’s easily overseen.
* We do use Rails, so I included @class_cache_storage Caches::Storage::Global@ as suggested “here”:http://rashkovskii.com/articles/2007/4/1/ongoing-improvements-in-caches-rb
* For some reason (I suspect my shallow knowledge of Ruby ;-), I did not manage to successfully _require ‘caches.rb’_ from the plugin installation dir _#{RAILS_ROOT}/vendor/plugins/caches.rb/lib_, so I copied it to _#{RAILS_ROOT}/lib_, which helped.
* For similar reasons, I had to use a workaround to extend the class definition with caching, instead of the recommended way of extending _conf/environment.rb_ by @ActiveRecord::Base.extend Caches::ClassMethods@
So our class looks as follows:

require 'ferret'
include Ferret
require 'caches.rb'

class FIndex
  extend Caches
  ...
  def self.search(user=nil, results_per_page=10)
    ...
  end
  class_cache_storage Caches::Storage::Global
  class_caches :search
end

N.B.: The class to be cached works with Ferret and not the DB, so it did not inherit from ActiveRecord.

* For a pure RoR developer, the terminology may be a little confusing (which indicates that Yurii can deal with more programming languages than just Ruby):
** _class methods_ mentioned in the “library description”:http://pad.verbdev.com/cachesrb/ are obviously just a shorthand for “the methods of a class”
** in Yurii’s documentation, Ruby *class methods* are called _static methods_ (as known in C/C++ or Java), and their caching is supported by “class_caches”:http://rashkovskii.com/articles/2007/4/1/ongoing-improvements-in-caches-rb (feature not available in caches.rb 0.2.0 from gems or RubyForge, but included in the more recent versions from SVN, like 0.4.0 we are using)

2 comments

Comments are closed.