Rails ActionCaching с фрагментом Memcached, но действие все равно вызывается - PullRequest
2 голосов
/ 10 марта 2010

Я сталкиваюсь с чем-то странным. Я использую memcached с настройкой caches_action. Я делаю это в 4 разных контроллерах. В двух из них он работает безупречно (пока), хотя по общему признанию эти два контроллера менее сложны, чем два, в которых он, кажется, не работает. Я делаю что-то вроде этого:

caches_action :index, :expires_in => 6.hours, :cache_path => Proc.new {|controller| controller.send(:generate_cache_path) }, :layout => false, :if => Proc.new { |c| c.request.format.js? }

Цель вышеизложенного состоит в том, чтобы кэшировать некоторые результаты, которые зависят от параметров. Метод my: generate_cache_path просто учитывает некоторые параметры и переменные сеанса и создает уникальный ключ для memcached. Я вижу в memcached -vv, что это работает.

Что странно, так это то, что я получаю запрос от приложения rails на заданный ключ, и я вижу, что memcached (с -vv) получает запрос и отправляет ответ обратно. Но тогда мое действие все равно выполняется, и для того же ключа устанавливается новое значение, даже если заданы все одинаковые параметры. Я могу наблюдать, как это происходит. В контроллерах, где все работает, выполняется запрос фрагмента, он получает его, действие в контроллере останавливается и фрагмент возвращается.

Эти строки происходят от одного и того же запроса:

Cached fragment hit: views/items/?page=1&rp=10&srtn=created_at&srto=DESC.js

А потом:

Cached fragment miss: views/items/?page=1&rp=10&srtn=created_at&srto=DESC.js

Я не знаю, что с этим делать, или я делаю что-то глупое. Буду очень признателен за любую помощь или идеи, где я могу начать искать проблемы.

1 Ответ

1 голос
/ 10 марта 2010

Хорошо, поэтому я смотрел на это большую часть ночи (удивительно!) И отлаживал его до строки в vendor / rails / actionpack / lib / action_controller / caching / actions.rb .. .on строка 127 запускает метод следующим образом:

def cache_layout?
  @options[:layout] == false
end

Моя линия:

caches_action :index, :expires_in => 6.hours, :cache_path => Proc.new {|controller| controller.send(:generate_cache_path) }, :layout => false

Для меня это означает, что мы не хотим кэшировать макет, только действие. Но проверяя @options [: layout] == ​​false, затем, когда layout имеет значение false, сам метод возвращает true, говоря, что вы должны кэшировать макет.

Это похоже на ошибку для меня. На данный момент я только что изменил мою строку макета на: layout => true, и это, кажется, работает, но это явно нелогично.

Для справки, cache_layout? метод вызывается здесь:

def after(controller)
  return if controller.rendered_action_cache || !caching_allowed(controller)
  action_content = cache_layout? ? content_for_layout(controller) : controller.response.body
  controller.write_fragment(controller.action_cache_path.path, action_content, @options[:store_options])
end

Это также вынуждает: layout => true в вызов рендеринга для любого действия. Вы будете запускаться из контроллера, что, честно говоря, не , что я хочу, чтобы произошло, если мне нужно установить его в: layout => true, чтобы получить cache_layout? вернуть ложь.

Как раз то, что я придумал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...