Rails 3.2 Rack::Cache HTTP-заголовки и кэширование действий
Добрый день,
Я столкнулся с некоторыми проблемами, пытаясь объединить кэширование HTTP с Rack::Cache и кэшированием действий (в моем приложении, размещенном на Heroku).
Использование их по отдельности, похоже, работает. При включенном кешировании действий загрузка страницы происходит быстро, и в журнале можно предположить, что она кешируется. При использовании HTTP-кэширования в контроллерах (eTag, last_modified и fresh_when) правильные заголовки представляются установленными.
Тем не менее, когда я пытаюсь объединить их, это выглядит как кэширование действий, но заголовки HTTP всегда max_age: 0, must_revalidate. Почему это? Я делаю что-то неправильно?
Например, вот код в моем "домашнем" действии:
class StaticPagesController < ApplicationController
layout 'public'
caches_action :about, :contact, ......, :home, .....
......
def home
last_modified = File.mtime("#{Rails.root}/app/views/static_pages/home.html.haml")
fresh_when last_modified: last_modified , public: true, etag: last_modified
expires_in 10.seconds, :public => true
end
Для всех намерений и целей у этого должен быть общедоступный тег контроля кэша с максимальным возрастом 10 нет?
$ curl -I http://myapp-staging.herokuapp.com/
HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Content-Type: text/html; charset=utf-8
Date: Thu, 24 May 2012 06:50:45 GMT
Etag: "997dacac05aa4c73f5a6861c9f5a9db0"
Status: 200 OK
Vary: Accept-Encoding
X-Rack-Cache: stale, invalid
X-Request-Id: 078d86423f234da1ac41b418825618c2
X-Runtime: 0.005902
X-Ua-Compatible: IE=Edge,chrome=1
Connection: keep-alive
Информация о конфигурации:
# Use a different cache store in production
config.cache_store = :dalli_store
config.action_dispatch.rack_cache = {
:verbose => true,
:metastore => "memcached://#{ENV['MEMCACHE_SERVERS']}",
:entitystore => "memcached://#{ENV['MEMCACHE_SERVERS']}"#,
}
На мой взгляд, вы должны быть в состоянии использовать кеширование действий, а также правильный обратный прокси-сервер? Я знаю, что они делают довольно похожие вещи (если страница изменится, и прокси, и кэш действий будут недействительными и их необходимо будет восстановить), но я чувствую, что у меня должно быть и то, и другое. Или я должен избавиться от одного?
ОБНОВИТЬ
Спасибо за ответ ниже! Вроде работает. Но чтобы избежать необходимости писать методы set_XXX_cache_header для каждого действия контроллера, видите ли вы причину, по которой это не сработает?
before_filter :set_http_cache_headers
.....
def set_http_cache_headers
expires_in 10.seconds, :public => true
last_modified = File.mtime("#{Rails.root}/app/views/static_pages/#{params[:action]}.html.haml")
fresh_when last_modified: last_modified , public: true, etag: last_modified
end
1 ответ
При использовании кэширования действий кэшируются только тело ответа и тип содержимого. Любые другие изменения в ответе не произойдут при последующих запросах.
Тем не менее, кэширование действий будет выполняться перед фильтрами, даже если само действие кэшируется.
Итак, вы можете сделать что-то вроде этого:
class StaticPagesController < ApplicationController
layout 'public'
before_filter :set_home_cache_headers, :only => [:home]
caches_action :about, :contact, ......, :home, .....
......
def set_home_cache_headers
last_modified = File.mtime("#{Rails.root}/app/views/static_pages/home.html.haml")
fresh_when last_modified: last_modified , public: true, etag: last_modified
expires_in 10.seconds, public: true
end