ActiveResource Кэширование

Как бы вы кэшировали модель ActiveResource? Желательно в memcached. Прямо сейчас он вытягивает модель из моего REST API, но каждый раз извлекает десятки записей. Лучше всего их кешировать.

3 ответа

Решение

Я играл с той же самой вещью, и я думаю, что я нашел довольно простой способ проверить redis для кэшированного объекта сначала. Это будет работать только тогда, когда вы используете метод поиска, но для моих нужд, я думаю, этого достаточно.

Переопределив find, я могу проверить контрольную сумму аргументов, чтобы увидеть, сохранен ли ответ в redis. Если я это сделаю, я могу извлечь ответ JSON из redis и создать новый объект прямо здесь. Если я этого не сделаю, я передам результаты поиска в ActiveResource::Base, и произойдет обычное действие.

Я еще не реализовал сохранение ответов в redis с помощью ActiveResource, но я планирую заполнить эти кеши в других местах. Таким образом, обычно я могу рассчитывать на то, что мои кеши есть, но если нет, я могу прибегнуть к API.

class MyResource < ActiveResource::Base
  class << self
    def find(*arguments)
      checksum = Digest::MD5.hexdigest(arguments.md5key)
      cached = $redis.get "cache:#{self.element_name}:#{checksum}"
      if cached
        return self.new JSON.parse(cached)
      end

      scope   = arguments.slice!(0)
      options = arguments.slice!(0) || {}
      super scope, options
    end
  end
end

и небольшой патч, чтобы мы могли получить ключ md5 для нашего массива:

require 'digest/md5'

class Object
  def md5key
    to_s
  end
end

class Array
  def md5key
    map(&:md5key).join
  end
end

class Hash
  def md5key
    sort.map(&:md5key).join
  end
end

Это помогает?

Я бы посоветовал заглянуть на https://github.com/Ahsizara/cached_resource, почти вся работа для вас сделана через самоцвет.

Кэширование в рельсах настраивается. Вы можете настроить кеш для поддержки memcached. Как правило, вы можете кэшировать при получении. Неясно, являетесь ли вы потребителем отдыха или услугой, но это действительно не имеет значения. Если вы кешируете данные на чтение (или извлекаете), а затем читаете кеш в следующий раз, все будет работать нормально. Если вы извлекаете данные из базы данных, обслуживаете кеш, а если кеш не доступен, кешируйте чтение из базы данных.

Я написал об этом в блоге здесь: http://squarism.com/2011/08/30/memcached-with-rails-3/

Однако то, о чем я писал, действительно довольно просто. Просто показывает, как избежать дорогостоящей операции с чем-то похожим на оператор ||=. Для лучшего примера, у новой реликвии есть эпизод масштабирования рельсов. Например, они показывают, как кэшировать последние 10 сообщений:

def self.recent
  Rails.cache.fetch("recent_posts", :expires_in => 30.minutes) do
    self.find(:all, :limit => 10)
  end
end

Rails.cache был настроен как кеш memcached, это настраиваемая часть, о которой я говорил.

Другие вопросы по тегам