2012-05-31 73 views
3

下午好,的Rails 3.2機架::緩存HTTP標頭和動作緩存

我(對我的Heroku代管的應用程式)碰到一些問題試圖HTTP緩存與機架結合:: Cache和動作緩存。

單獨使用它們,它似乎正在工作。啓用動作緩存後,頁面加載速度很快,並且日誌會顯示它正在緩存。通過控制器中的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 

對於所有意圖和目的,這應該有一個公共的Cache-Control標籤與10 max-age的沒有?

$ 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']}"#, 
} 

在我心中,你應該能夠使用動作緩存以及正確的反向代理?我知道他們做了相當類似的事情(如果頁面發生變化,代理和動作緩存都將失效並需要重新生成),但是我覺得我應該可以在其中擁有兩者。或者我應該擺脫一個?

UPDATE

感謝下面的答案!它似乎工作。但爲了避免爲每個控制器操作編寫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 

回答

5

當您使用動作緩存時,只緩存響應正文和內容類型。對後續請求不會發生其他任何對響應的更改。

但是,即使動作本身被緩存,動作緩存也會在過濾器之前運行。

所以,你可以做這樣的事情:

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 
+0

感謝您的輸入!我會給你一個鏡頭,看看它是如何爲我工作的。 – Brandon

+1

這似乎工作!但是,如果您不介意檢查它(避免編寫18個單獨的方法的潛在方法),我在更新中確實有一個快速問題。 – Brandon

+0

請注意''before_filter'確實需要在調用'caches_action'之前被列出(如上所示),以確保過濾器按正確的順序運行,因爲這首先讓我跳起來了。 –