impress/app/models/item/proxy.rb
Matchu e42de795dd Use item proxies for JSON caching
That is, once we get our list of IDs from the search engine, only
fetch records whose JSON we don't already have cached.

It's simpler here to use as_json, but it'd probably be even faster
if I figure out how to serve a plain JSON string from a Rails
controller. In the meantime, requests of entirely cached items
are coming in at about 85ms on average on my box (dev, cache
classes, many items), about 10ms better than the last
iteration.
2013-06-26 23:01:12 -07:00

45 lines
No EOL
1.2 KiB
Ruby

class Item
class Proxy
include FragmentLocalization
attr_reader :id
attr_writer :item
def initialize(id)
@id = id
@known_method_outputs = {}
end
def method_cached?(method_name)
# TODO: is there a way to cache nil? Right now we treat is as a miss.
# We eagerly read the cache rather than just check if the value exists,
# which will usually cut down on cache requests.
@known_method_outputs[method_name] ||= Rails.cache.read(
method_fragment_key(method_name))
!@known_method_outputs[method_name].nil?
end
def as_json(options={})
cache_method(:as_json)
end
private
def cache_method(method_name, &block)
# Two layers of cache: a local copy, in case the method is called again,
# and then the Rails cache, before we hit the actual method call.
@known_method_outputs[method_name] ||= begin
key = method_fragment_key(method_name)
Rails.cache.fetch(key) { item.send(method_name) }
end
end
def item
@item ||= Item.find(@id)
end
def method_fragment_key(method_name)
localize_fragment_key("item/#{@id}##{method_name}", I18n.locale)
end
end
end