Skip to content
Browse files

Provide a class optin for page_cache_compression.

  • Loading branch information...
1 parent 7b1ac55 commit 39081f166023092041605144c87d7a6cd3b65102 @josevalim josevalim committed Dec 24, 2011
Showing with 24 additions and 20 deletions.
  1. +20 −17 actionpack/lib/action_controller/caching/pages.rb
  2. +4 −3 actionpack/test/controller/caching_test.rb
37 actionpack/lib/action_controller/caching/pages.rb
@@ -16,7 +16,7 @@ module Caching
# caches_page :show, :new
# end
- # This will generate cache files such as <tt>weblog/show/5.html</tt> and <tt>weblog/new.html</tt>, which match the URLs used
+ # This will generate cache files such as <tt>weblog/show/5.html</tt> and <tt>weblog/new.html</tt>, which match the URLs used
# that would normally trigger dynamic page generation. Page caching works by configuring a web server to first check for the
# existence of files on disk, and to serve them directly when found, without passing the request through to Action Pack.
# This is much faster than handling the full dynamic request in the usual way.
@@ -38,23 +38,25 @@ module Pages
extend ActiveSupport::Concern
included do
- ##
- # :singleton-method:
# The cache directory should be the document root for the web server and is set using <tt>Base.page_cache_directory = "/document/root"</tt>.
# For Rails, this directory has already been set to Rails.public_path (which is usually set to <tt>Rails.root + "/public"</tt>). Changing
# this setting can be useful to avoid naming conflicts with files in <tt>public/</tt>, but doing so will likely require configuring your
# web server to look in the new location for cached files.
config_accessor :page_cache_directory
self.page_cache_directory ||= ''
- ##
- # :singleton-method:
# Most Rails requests do not have an extension, such as <tt>/weblog/new</tt>. In these cases, the page caching mechanism will add one in
# order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is <tt>.html</tt>.
# If you want something else, like <tt>.php</tt> or <tt>.shtml</tt>, just set Base.page_cache_extension. In cases where a request already has an
# extension, such as <tt>.xml</tt> or <tt>.rss</tt>, page caching will not add an extension. This allows it to work well with RESTful apps.
config_accessor :page_cache_extension
self.page_cache_extension ||= '.html'
+ # The compression used for gzip. If false (default), the page is not compressed.
+ # If can be a symbol showing the ZLib compression method, for example, :best_compression
+ # or :best_speed or an integer configuring the compression level.
+ config_accessor :page_cache_compression
+ self.page_cache_compression ||= false
module ClassMethods
@@ -85,10 +87,11 @@ def cache_page(content, path, extension = nil, gzip = Zlib::BEST_COMPRESSION)
- # Caches the +actions+ using the page-caching approach that'll store the cache in a path within the page_cache_directory that
+ # Caches the +actions+ using the page-caching approach that'll store
+ # the cache in a path within the page_cache_directory that
# matches the triggering url.
- # You can disable gzipping by setting +:gzip+ option to false.
+ # You can also pass a :gzip option to override the class configuration one.
# Usage:
@@ -104,16 +107,16 @@ def caches_page(*actions)
return unless perform_caching
options = actions.extract_options!
- gzip_level = options.fetch(:gzip, :best_compression)
- if gzip_level
- gzip_level = case gzip_level
- when Symbol
- Zlib.const_get(gzip_level.to_s.upcase)
- when Fixnum
- gzip_level
- else
- end
+ gzip_level = options.fetch(:gzip, page_cache_compression)
+ gzip_level = case gzip_level
+ when Symbol
+ Zlib.const_get(gzip_level.to_s.upcase)
+ when Fixnum
+ gzip_level
+ when false
+ nil
+ else
after_filter({:only => actions}.merge(options)) do |c|
7 actionpack/test/controller/caching_test.rb
@@ -14,14 +14,15 @@ class CachingController < ActionController::Base
class PageCachingTestController < CachingController
+ self.page_cache_compression = :best_compression
caches_page :ok, :no_content, :if => { |c| !c.request.format.json? }
caches_page :found, :not_found
caches_page :about_me
caches_page :default_gzip
caches_page :no_gzip, :gzip => false
caches_page :gzip_level, :gzip => :best_speed
def ok
head :ok
@@ -144,7 +145,7 @@ def test_should_allow_to_disable_gzip
assert !File.exist?("#{FILE_STORE_PATH}/page_caching_test/no_gzip.html.gz")
- def test_should_use_best_gzip_by_default
+ def test_should_use_config_gzip_by_default
@controller.expects(:cache_page).with(nil, nil, Zlib::BEST_COMPRESSION)
get :default_gzip
@@ -233,7 +234,7 @@ class ActionCachingTestController < CachingController
caches_action :show, :cache_path => ''
caches_action :edit, :cache_path => { |c| c.params[:id] ? "{c.params[:id]};edit" : "" }
caches_action :with_layout
- caches_action :with_format_and_http_param, :cache_path => { |c| { :key => 'value' } }
+ caches_action :with_format_and_http_param, :cache_path => { |c| { :key => 'value' } }
caches_action :layout_false, :layout => false
caches_action :record_not_found, :four_oh_four, :simple_runtime_error

7 comments on commit 39081f1

ai commented on 39081f1 Jan 8, 2012

Why compression is disabled by default? For most cases it is best solution (because, without compression nginx will take more CPU by stream compression).

Ruby on Rails member

The compression is not in the streamed file, but in the file written to the filesystem and nginx/apache will know how to serve it only if you configure it. So it would never work by default.

ai commented on 39081f1 Jan 9, 2012

@josevalim, but for assets you need to configure nginx too, but file are gziped by default.

Ruby on Rails member
fxn commented on 39081f1 Jan 9, 2012

Background: In the case of assets I remember talking with Josh about it (I wrote the compression in sprockets). It was decided to generate the gzipped files with no way to opt-out (I don't know if it is still the case) because it was fast and if you do not have the web server configured the .gz files are just ignored. If users come in hordes needing a flag one could be added :).

Not saying page caching should do the same, just giving context re assets.

Ruby on Rails member

Exactly, assets pre-compilation does not happen during the request and therefore becomes quite cheap. pages cache configuration happens in the middle of the request and people should opt-in paying close attention to the compression algorithm they choose.

ai commented on 39081f1 Jan 9, 2012

But page cache is not to often operation (because it is cache) and compression is very fast operation.

Ruby on Rails member
drogus commented on 39081f1 Jan 9, 2012

@ai you can't predict how caching looks like on user's apps

Please sign in to comment.
Something went wrong with that request. Please try again.