Skip to content

Instantly share code, notes, and snippets.

@actsasflinn
Created August 3, 2009 03:35
Show Gist options
  • Save actsasflinn/160348 to your computer and use it in GitHub Desktop.
Save actsasflinn/160348 to your computer and use it in GitHub Desktop.
experiment with Tokyo Tyrant as an ActiveRecord cache layer
require 'tokyo_tyrant'
$tyrant = TokyoTyrant::Table.new
module Cacheable
module TyrantTable
def self.included(base) #:nodoc:
super
base.class_eval %q{
cattr_accessor :cache_records
@@cache_records = false
}
base.extend ClassMethods
end
module ClassMethods #:nodoc:
# Expire cache by args
def clear_tyrant(key = '')
$tyrant.delete_keys_with_prefix(self.cache_key(key))
end
def find_with_tyrant(n)
instantiate($tyrant.fetch(cache_key(n)){ find(n).to_tyrant })
end
def [](n)
find_with_tyrant(n)
end unless method_defined?(:[])
end
def to_tyrant
attributes.dup.merge("type" => self.class.name)
end
# Expire cache for a record
def clear_tyrant
self.class.clear_tyrant(self.to_param) unless self.new_record?
end
# Cache a record by ID
def store_record(options = {})
options = { :force => false }.merge(options)
key = options.delete(:key) || self.cache_key
$tyrant.fetch(key, options[:force]){ self.to_tyrant } unless self.new_record?
end
# Cache all found records, warning!
def after_find
self.store_record if self.class.cache_records
true
end
# Reset cache for all records after save, warning!
def after_save
super
self.store_record(:force => true) unless self.class.cache_records
true
end
end
end
class Foo < ActiveRecord::Base
include Cacheable::TyrantTable
end
# Awesomeness Follows
Foo[1] # Fetch from Tyrant
# => #<Foo id: 1, bar: "baz">
Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
# against mysql on localhost
b.report('find') do
10000.times do
Foo.find(3)
end
end
# against tokyo tyrant on localhost
b.report('find_with_tyrant') do
10000.times do
Foo[3]
end
end
end
=begin results
user system total real
find 3.300000 0.320000 3.620000 ( 4.803466)
find_with_tyrant 1.370000 0.230000 1.600000 ( 2.702054)
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment