Rails 3.2 Rack::Cache HTTP заглавки и кеширане на действия

Добър ден,

Сблъсках се с някои проблеми, опитвайки се да комбинирам HTTP кеширане с Rack::Cache и кеширане на действия (в моето приложение, хоствано от Heroku).

Използвайки ги поотделно, изглежда, че работи. При активирано кеширане на действие страницата се зарежда бързо и регистрационният файл предполага, че се кешира. С HTTP кеширане в контролерите (eTag, last_modified и fresh_when) правилните заглавки изглежда са зададени.

Въпреки това, когато се опитам да комбинирам двете, изглежда, че това е кеширане на действие, но HTTP заглавките винаги са max_age: 0, must_revalidate. Защо е това? Правя ли нещо нередно?

Например, ето кода в моето действие "home":

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

person Brandon    schedule 31.05.2012    source източник


Отговори (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
person Dan Weinand    schedule 03.07.2012
comment
Благодаря за приноса! Ще пробвам и ще видя как ще ми подейства. - person Brandon; 04.07.2012
comment
Това изглежда работи! Но имам бърз въпрос в актуализацията, ако нямате нищо против да я проверите (потенциален начин да избегнете писането на 18 отделни метода). - person Brandon; 04.07.2012
comment
Обърнете внимание, че before_filter трябва да бъде посочен ПРЕДИ извикването на caches_action (както е показано по-горе), за да се гарантира, че филтрите се изпълняват в правилния ред, тъй като това ме спъна в началото. - person Stuart M; 04.01.2013