From 03bb1ebec513de779908af110c46e16b9c882673 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 4 Feb 2009 01:44:58 +0000 Subject: Convert the guides from asciidoc to textile and integrate with the new design. If you're a guide writer and want to generate the guides, Run : ruby railties/guides/rails_guides.rb And guides HTML will get generated inside railties/guides/output directory. --- railties/guides/source/caching_with_rails.textile | 429 ++++++++++++++++++++++ 1 file changed, 429 insertions(+) create mode 100644 railties/guides/source/caching_with_rails.textile (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile new file mode 100644 index 0000000000..456b0c48a7 --- /dev/null +++ b/railties/guides/source/caching_with_rails.textile @@ -0,0 +1,429 @@ +h2. Caching with Rails: An overview + +Everyone caches. This guide will teach you what you need to know about +avoiding that expensive round-trip to your database and returning what you +need to return to those hungry web clients in the shortest time possible. + +endprologue. + +h3. Basic Caching + +This is an introduction to the three types of caching techniques that Rails +provides by default without the use of any third party plugins. + +To get started make sure +config.action_controller.perform_caching+ is set +to +true+ for your environment. This flag is normally set in the +corresponding config/environments/*.rb and caching is disabled by default +there for development and test, and enabled for production. + + +config.action_controller.perform_caching = true + + +h4. Page Caching + +Page caching is a Rails mechanism which allows the request for a generated +page to be fulfilled by the webserver, without ever having to go through the +Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be +applied to every situation (such as pages that need authentication) and since +the webserver is literally just serving a file from the filesystem, cache +expiration is an issue that needs to be dealt with. + +So, how do you enable this super-fast cache behavior? Simple, let's say you +have a controller called ProductsController and a 'list' action that lists all +the products + + +class ProductsController < ActionController + + caches_page :index + + def index; end + +end + + +The first time anyone requests products/index, Rails will generate a file +called +index.html+ and the webserver will then look for that file before it +passes the next request for products/index to your Rails application. + +By default, the page cache directory is set to Rails.public_path (which is +usually set to +RAILS_ROOT + "/public"+) and this can be configured by +changing the configuration setting +config.action_controller.page_cache_directory+. +Changing the default from /public helps avoid naming conflicts, since you may +want to put other static html in /public, but changing this will require web +server reconfiguration to let the web server know where to serve the cached +files from. + +The Page Caching mechanism will automatically add a +.html+ exxtension to +requests for pages that do not have an extension to make it easy for the +webserver to find those pages and this can be configured by changing the +configuration setting +config.action_controller.page_cache_extension+. + +In order to expire this page when a new product is added we could extend our +example controler like this: + + +class ProductsController < ActionController + + caches_page :list + + def list; end + + def create + expire_page :action => :list + end + +end + + +If you want a more complicated expiration scheme, you can use cache sweepers +to expire cached objects when things change. This is covered in the section on Sweepers. + +[More: caching paginated results? more examples? Walk-through of page caching?] + +h4. Action Caching + +One of the issues with Page Caching is that you cannot use it for pages that +require to restrict access somehow. This is where Action Caching comes in. +Action Caching works like Page Caching except for the fact that the incoming +web request does go from the webserver to the Rails stack and Action Pack so +that before filters can be run on it before the cache is served, so that +authentication and other restrictions can be used while still serving the +result of the output from a cached copy. + +Clearing the cache works in the exact same way as with Page Caching. + +Let's say you only wanted authenticated users to edit or create a Product +object, but still cache those pages: + + +class ProductsController < ActionController + + before_filter :authenticate, :only => [ :edit, :create ] + caches_page :list + caches_action :edit + + def list; end + + def create + expire_page :action => :list + expire_action :action => :edit + end + + def edit; end + +end + + +And you can also use +:if+ (or +:unless+) to pass a Proc that specifies when the +action should be cached. Also, you can use +:layout => false+ to cache without +layout so that dynamic information in the layout such as logged in user info +or the number of items in the cart can be left uncached. This feature is +available as of Rails 2.2. + + +[More: more examples? Walk-through of Action Caching from request to response? + Description of Rake tasks to clear cached files? Show example of + subdomain caching? Talk about :cache_path, :if and assing blocks/Procs + to expire_action?] + +h4. Fragment Caching + +Life would be perfect if we could get away with caching the entire contents of +a page or action and serving it out to the world. Unfortunately, dynamic web +applications usually build pages with a variety of components not all of which +have the same caching characteristics. In order to address such a dynamically +created page where different parts of the page need to be cached and expired +differently Rails provides a mechanism called Fragment Caching. + +Fragment Caching allows a fragment of view logic to be wrapped in a cache +block and served out of the cache store when the next request comes in. + +As an example, if you wanted to show all the orders placed on your website +in real time and didn't want to cache that part of the page, but did want +to cache the part of the page which lists all products available, you +could use this piece of code: + + +<% Order.find_recent.each do |o| %> + <%= o.buyer.name %> bought <% o.product.name %> +<% end %> + +<% cache do %> + All available products: + <% Product.find(:all).each do |p| %> + <%= link_to p.name, product_url(p) %> + <% end %> +<% end %> + + +The cache block in our example will bind to the action that called it and is +written out to the same place as the Action Cache, which means that if you +want to cache multiple fragments per action, you should provide an +action_suffix+ to the cache call: + + +<% cache(:action => 'recent', :action_suffix => 'all_products') do %> + All available products: + + +and you can expire it using the +expire_fragment+ method, like so: + + +expire_fragment(:controller => 'products', :action => 'recent', :action_suffix => 'all_products) + + +If you don't want the cache block to bind to the action that called it, You can +also use globally keyed fragments by calling the cache method with a key, like +so: + + +<% cache(:key => ['all_available_products', @latest_product.created_at].join(':')) do %> + All available products: +<% end %> + + +This fragment is then available to all actions in the ProductsController using +the key and can be expired the same way: + + +expire_fragment(:key => ['all_available_products', @latest_product.created_at].join(':')) + + +[More: more examples? description of fragment keys and expiration, etc? pagination?] + +h4. Sweepers + +Cache sweeping is a mechanism which allows you to get around having a ton of +expire_{page,action,fragment} calls in your code by moving all the work +required to expire cached content into a +ActionController::Caching::Sweeper+ +class that is an Observer and looks for changes to an object via callbacks, +and when a change occurs it expires the caches associated with that object n +an around or after filter. + +Continuing with our Product controller example, we could rewrite it with a +sweeper such as the following: + + +class StoreSweeper < ActionController::Caching::Sweeper + observe Product # This sweeper is going to keep an eye on the Product model + + # If our sweeper detects that a Product was created call this + def after_create(product) + expire_cache_for(product) + end + + # If our sweeper detects that a Product was updated call this + def after_update(product) + expire_cache_for(product) + end + + # If our sweeper detects that a Product was deleted call this + def after_destroy(product) + expire_cache_for(product) + end + + private + def expire_cache_for(record) + # Expire the list page now that we added a new product + expire_page(:controller => '#{record}', :action => 'list') + + # Expire a fragment + expire_fragment(:controller => '#{record}', :action => 'recent', :action_suffix => 'all_products') + end +end + + +Then we add it to our controller to tell it to call the sweeper when certain +actions are called. So, if we wanted to expire the cached content for the +list and edit actions when the create action was called, we could do the +following: + + +class ProductsController < ActionController + + before_filter :authenticate, :only => [ :edit, :create ] + caches_page :list + caches_action :edit + cache_sweeper :store_sweeper, :only => [ :create ] + + def list; end + + def create + expire_page :action => :list + expire_action :action => :edit + end + + def edit; end + +end + + +[More: more examples? better sweepers?] + +h4. SQL Caching + +Query caching is a Rails feature that caches the result set returned by each +query so that if Rails encounters the same query again for that request, it +will used the cached result set as opposed to running the query against the +database again. + +For example: + + +class ProductsController < ActionController + + before_filter :authenticate, :only => [ :edit, :create ] + caches_page :list + caches_action :edit + cache_sweeper :store_sweeper, :only => [ :create ] + + def list + # Run a find query + Product.find(:all) + + ... + + # Run the same query again + Product.find(:all) + end + + def create + expire_page :action => :list + expire_action :action => :edit + end + + def edit; end + +end + + +In the 'list' action above, the result set returned by the first +Product.find(:all) will be cached and will be used to avoid querying the +database again the second time that finder is called. + +Query caches are created at the start of an action and destroyed at the end of +that action and thus persist only for the duration of the action. + +h4. Cache stores + +Rails provides different stores for the cached data for action and fragment +caches. Page caches are always stored on disk. + +The cache stores provided include: + +1) Memory store: Cached data is stored in the memory allocated to the Rails + process, which is fine for WEBrick and for FCGI (if you + don't care that each FCGI process holds its own fragment + store). It's not suitable for CGI as the process is thrown + away at the end of each request. It can potentially also + take up a lot of memory since each process keeps all the + caches in memory. + + +ActionController::Base.cache_store = :memory_store + + +2) File store: Cached data is stored on the disk, this is the default store + and the default path for this store is: /tmp/cache. Works + well for all types of environments and allows all processes + running from the same application directory to access the + cached content. + + + +ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" + + +3) DRb store: Cached data is stored in a separate shared DRb process that all + servers communicate with. This works for all environments and + only keeps one cache around for all processes, but requires + that you run and manage a separate DRb process. + + +ActionController::Base.cache_store = :drb_store, "druby://localhost:9192" + + +4) MemCached store: Works like DRbStore, but uses Danga's MemCache instead. + Rails uses the bundled memcached-client gem by default. + + +ActionController::Base.cache_store = :mem_cache_store, "localhost" + + +5) Custom store: You can define your own cache store (new in Rails 2.1) + + +ActionController::Base.cache_store = MyOwnStore.new("parameter") + + ++Note: config.cache_store can be used in place of +ActionController::Base.cache_store in your Rails::Initializer.run block in +environment.rb+ + +h3. Conditional GET support + +Conditional GETs are a facility of the HTTP spec that provide a way for web +servers to tell browsers that the response to a GET request hasn’t changed +since the last request and can be safely pulled from the browser cache. + +They work by using the HTTP_IF_NONE_MATCH and HTTP_IF_MODIFIED_SINCE headers to +pass back and forth both a unique content identifier and the timestamp of when +the content was last changed. If the browser makes a request where the content +identifier (etag) or last modified since timestamp matches the server’s version +then the server only needs to send back an empty response with a not modified +status. + +It is the server’s (i.e. our) responsibility to look for a last modified +timestamp and the if-none-match header and determine whether or not to send +back the full response. With conditional-get support in rails this is a pretty +easy task: + + +class ProductsController < ApplicationController + + def show + @product = Product.find(params[:id]) + + # If the request is stale according to the given timestamp and etag value + # (i.e. it needs to be processed again) then execute this block + if stale?(:last_modified => @product.updated_at.utc, :etag => @product) + respond_to do |wants| + # ... normal response processing + end + end + + # If the request is fresh (i.e. it's not modified) then you don't need to do + # anything. The default render checks for this using the parameters + # used in the previous call to stale? and will automatically send a + # :not_modified. So that's it, you're done. +end + + +If you don’t have any special response processing and are using the default +rendering mechanism (i.e. you’re not using respond_to or calling render +yourself) then you’ve got an easy helper in fresh_when: + + +class ProductsController < ApplicationController + + # This will automatically send back a :not_modified if the request is fresh, + # and will render the default template (product.*) if it's stale. + + def show + @product = Product.find(params[:id]) + fresh_when :last_modified => @product.published_at.utc, :etag => @article + end +end + + +h3. Advanced Caching + +Along with the built-in mechanisms outlined above, a number of excellent +plugins exist to help with finer grained control over caching. These include +Chris Wanstrath's excellent cache_fu plugin (more info here: +http://errtheblog.com/posts/57-kickin-ass-w-cachefu) and Evan Weaver's +interlock plugin (more info here: +http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/). Both +of these plugins play nice with memcached and are a must-see for anyone +seriously considering optimizing their caching needs. -- cgit v1.2.3 From 1a8226977f515331d4bddc346a4f0c4583f67e6c Mon Sep 17 00:00:00 2001 From: James Miller Date: Fri, 6 Feb 2009 07:59:02 -0800 Subject: Fix spelling errors in caching guide --- railties/guides/source/caching_with_rails.textile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 940466ecb3..f4fb8ec348 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -55,13 +55,13 @@ want to put other static html in /public, but changing this will require web server reconfiguration to let the web server know where to serve the cached files from. -The Page Caching mechanism will automatically add a +.html+ exxtension to +The Page Caching mechanism will automatically add a +.html+ extension to requests for pages that do not have an extension to make it easy for the webserver to find those pages and this can be configured by changing the configuration setting +config.action_controller.page_cache_extension+. In order to expire this page when a new product is added we could extend our -example controler like this: +example controller like this: class ProductsController < ActionController -- cgit v1.2.3 From b9e87f46791d81083c8d44890cd50a03c1c0b7fa Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Sun, 22 Feb 2009 18:45:17 -0500 Subject: Added info about parameters passed to caches_action and removed More: blocks to clean up a little --- railties/guides/source/caching_with_rails.textile | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index f4fb8ec348..d77f48929d 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -80,8 +80,6 @@ end If you want a more complicated expiration scheme, you can use cache sweepers to expire cached objects when things change. This is covered in the section on Sweepers. -[More: caching paginated results? more examples? Walk-through of page caching?] - h4. Action Caching One of the issues with Page Caching is that you cannot use it for pages that @@ -122,11 +120,14 @@ layout so that dynamic information in the layout such as logged in user info or the number of items in the cart can be left uncached. This feature is available as of Rails 2.2. +You can modify the default action cache path by passing a +:cache_path+ option. +This will be passed directly to ActionCachePath.path_for. This is handy for +actions with multiple possible routes that should be cached differently. If +a block is given, it is called with the current controller instance. -[More: more examples? Walk-through of Action Caching from request to response? - Description of Rake tasks to clear cached files? Show example of - subdomain caching? Talk about :cache_path, :if and assing blocks/Procs - to expire_action?] +Finally, if you are using memcached, you can also pass +:expires_in+. In fact, +all parameters not used by caches_action are sent to the underlying cache +store. h4. Fragment Caching @@ -190,8 +191,6 @@ the key and can be expired the same way: expire_fragment(:key => ['all_available_products', @latest_product.created_at].join(':')) -[More: more examples? description of fragment keys and expiration, etc? pagination?] - h4. Sweepers Cache sweeping is a mechanism which allows you to get around having a ton of @@ -259,8 +258,6 @@ class ProductsController < ActionController end -[More: more examples? better sweepers?] - h4. SQL Caching Query caching is a Rails feature that caches the result set returned by each -- cgit v1.2.3 From 7cf3822c5624cca530afa8481956142dfff6cca3 Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Mon, 23 Feb 2009 00:43:38 -0500 Subject: Updated with all the new cache_store stuff --- railties/guides/source/caching_with_rails.textile | 113 ++++++++++++++++++---- 1 file changed, 92 insertions(+), 21 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index d77f48929d..b7082e8092 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -304,51 +304,110 @@ that action and thus persist only for the duration of the action. h4. Cache stores -Rails provides different stores for the cached data for action and fragment -caches. Page caches are always stored on disk. +Rails (as of 2.1) provides different stores for the cached data for action and +fragment caches. Page caches are always stored on disk. -The cache stores provided include: +Rails 2.1 and above provide ActiveSupport::Cache::Store which can be used to +cache strings. Some cache store implementations, like MemoryStore, are able to +cache arbitrary Ruby objects, but don‘t count on every cache store to be able +to do that. -1) Memory store: Cached data is stored in the memory allocated to the Rails - process, which is fine for WEBrick and for FCGI (if you - don't care that each FCGI process holds its own fragment - store). It's not suitable for CGI as the process is thrown - away at the end of each request. It can potentially also - take up a lot of memory since each process keeps all the - caches in memory. +The default cache stores provided include: + +1) ActiveSupport::Cache::MemoryStore: A cache store implementation which stores +everything into memory in the same process. If you‘re running multiple Ruby on +Rails server processes (which is the case if you‘re using mongrel_cluster or +Phusion Passenger), then this means that your Rails server process instances +won‘t be able to share cache data with each other. If your application never +performs manual cache item expiry (e.g. when you‘re using generational cache +keys), then using +MemoryStore+ is ok. Otherwise, consider carefully whether you +should be using this cache store. + ++MemoryStore+ is not only able to store strings, but also arbitrary Ruby objects. + ++MemoryStore+ is not thread-safe. Use +SynchronizedMemoryStore+ instead if you +need thread-safety. + ActionController::Base.cache_store = :memory_store -2) File store: Cached data is stored on the disk, this is the default store - and the default path for this store is: /tmp/cache. Works - well for all types of environments and allows all processes - running from the same application directory to access the - cached content. +2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk, this is +the default store and the default path for this store is: /tmp/cache. Works +well for all types of environments and allows all processes running from the +same application directory to access the cached content. If /tmp/cache does not +exist, the default store becomes MemoryStore. ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" -3) DRb store: Cached data is stored in a separate shared DRb process that all - servers communicate with. This works for all environments and - only keeps one cache around for all processes, but requires - that you run and manage a separate DRb process. +3) ActiveSupport::Cache::DRbStore: Cached data is stored in a separate shared +DRb process that all servers communicate with. This works for all environments +and only keeps one cache around for all processes, but requires that you run +and manage a separate DRb process. + ActionController::Base.cache_store = :drb_store, "druby://localhost:9192" 4) MemCached store: Works like DRbStore, but uses Danga's MemCache instead. - Rails uses the bundled memcached-client gem by default. +Rails uses the bundled memcached-client gem by default. This is currently the +most popular cache store for production websites. + +Special features: + * Clustering and load balancing. One can specify multiple memcached servers, + and MemCacheStore will load balance between all available servers. If a + server goes down, then MemCacheStore will ignore it until it goes back + online. + * Time-based expiry support. See write and the +:expires_in+ option. + * Per-request in memory cache for all communication with the MemCache server(s). + +It also accepts a hash of additional options: + + * :namespace - specifies a string that will automatically be prepended to keys when accessing the memcached store. + * :readonly - a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. + * :multithread - a boolean value that adds thread safety to read/write operations - it is unlikely you’ll need to use this option as the Rails threadsafe! method offers the same functionality. + +The read and write methods of the MemCacheStore accept an options hash too. +When reading you can specify :raw => true to prevent the object being marshaled +(by default this is false which means the raw value in the cache is passed to +Marshal.load before being returned to you.) + +When writing to the cache it is also possible to specify :raw => true means the +value is not passed to Marshal.dump before being stored in the cache (by +default this is false). + +The write method also accepts an :unless_exist flag which determines whether +the memcached add (when true) or set (when false) method is used to store the +item in the cache and an :expires_in option that specifies the time-to-live for +the cached item in seconds. + ActionController::Base.cache_store = :mem_cache_store, "localhost" -5) Custom store: You can define your own cache store (new in Rails 2.1) +5) ActiveSupport::Cache::SynchronizedMemoryStore: Like ActiveSupport::Cache::MemoryStore but thread-safe. + + + +ActionController::Base.cache_store = :synchronized_memory_store + + +6) ActiveSupport::Cache::CompressedMemCacheStore: Works just like the regular +MemCacheStore but uses GZip to decompress/compress on read/write. + + + +ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost" + + +7) Custom store: You can define your own cache store (new in Rails 2.1) + ActionController::Base.cache_store = MyOwnStore.new("parameter") @@ -358,6 +417,18 @@ ActionController::Base.cache_store = MyOwnStore.new("parameter") ActionController::Base.cache_store in your Rails::Initializer.run block in environment.rb+ +In addition to all of this, Rails also adds the ActiveRecord::Base#cache_key +method that generates a key using the class name, id and updated_at timestamp +(if available). + +An example: + + +Rails.cache.read("city") # => nil +Rails.cache.write("city", "Duckburgh") +Rails.cache.read("city") # => "Duckburgh" + + h3. Conditional GET support Conditional GETs are a facility of the HTTP spec that provide a way for web -- cgit v1.2.3 From 9deb327daa97da5c38c8e1d83b60e8723ef429a7 Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Mon, 23 Feb 2009 00:53:58 -0500 Subject: Added a changelog --- railties/guides/source/caching_with_rails.textile | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index b7082e8092..c2696aa1ba 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -495,3 +495,11 @@ interlock plugin (more info here: http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/). Both of these plugins play nice with memcached and are a must-see for anyone seriously considering optimizing their caching needs. + +h3. Changelog +"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching + +February 22, 2009: Beefed up the section on cache_stores +December 27, 2008: Typo fixes +November 23, 2008: Incremental updates with various suggested changes and formatting cleanup +September 15, 2008: Initial version by Aditya Chadha -- cgit v1.2.3 From 77aa8a6b815db56c530ef5270e4cd386940befac Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Mon, 23 Feb 2009 01:29:13 -0500 Subject: Take out some special characters that sneaked in --- railties/guides/source/caching_with_rails.textile | 31 ++++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index c2696aa1ba..cbe15689c1 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -309,14 +309,14 @@ fragment caches. Page caches are always stored on disk. Rails 2.1 and above provide ActiveSupport::Cache::Store which can be used to cache strings. Some cache store implementations, like MemoryStore, are able to -cache arbitrary Ruby objects, but don‘t count on every cache store to be able +cache arbitrary Ruby objects, but don't count on every cache store to be able to do that. The default cache stores provided include: 1) ActiveSupport::Cache::MemoryStore: A cache store implementation which stores -everything into memory in the same process. If you‘re running multiple Ruby on -Rails server processes (which is the case if you‘re using mongrel_cluster or +everything into memory in the same process. If you're running multiple Ruby on +Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances won‘t be able to share cache data with each other. If your application never performs manual cache item expiry (e.g. when you‘re using generational cache @@ -368,23 +368,24 @@ Special features: It also accepts a hash of additional options: - * :namespace - specifies a string that will automatically be prepended to keys when accessing the memcached store. - * :readonly - a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. - * :multithread - a boolean value that adds thread safety to read/write operations - it is unlikely you’ll need to use this option as the Rails threadsafe! method offers the same functionality. + * +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store. + * +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. + * +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. The read and write methods of the MemCacheStore accept an options hash too. -When reading you can specify :raw => true to prevent the object being marshaled +When reading you can specify +:raw => true+ to prevent the object being +marshaled (by default this is false which means the raw value in the cache is passed to Marshal.load before being returned to you.) -When writing to the cache it is also possible to specify :raw => true means the -value is not passed to Marshal.dump before being stored in the cache (by +When writing to the cache it is also possible to specify +:raw => true+ means +the value is not passed to Marshal.dump before being stored in the cache (by default this is false). -The write method also accepts an :unless_exist flag which determines whether +The write method also accepts an +:unless_exist+ flag which determines whether the memcached add (when true) or set (when false) method is used to store the -item in the cache and an :expires_in option that specifies the time-to-live for -the cached item in seconds. +item in the cache and an +:expires_in+ option that specifies the time-to-live +for the cached item in seconds. @@ -442,7 +443,7 @@ identifier (etag) or last modified since timestamp matches the server’s versio then the server only needs to send back an empty response with a not modified status. -It is the server’s (i.e. our) responsibility to look for a last modified +It is the server's (i.e. our) responsibility to look for a last modified timestamp and the if-none-match header and determine whether or not to send back the full response. With conditional-get support in rails this is a pretty easy task: @@ -468,8 +469,8 @@ class ProductsController < ApplicationController end -If you don’t have any special response processing and are using the default -rendering mechanism (i.e. you’re not using respond_to or calling render +If you don't have any special response processing and are using the default +rendering mechanism (i.e. you're not using respond_to or calling render yourself) then you’ve got an easy helper in fresh_when: -- cgit v1.2.3 From 8aec73304835e09fdeed903a5ad6ffe8105194fd Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Mon, 23 Feb 2009 01:35:15 -0500 Subject: More special character removal and added cache_money to the reference list --- railties/guides/source/caching_with_rails.textile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index cbe15689c1..56d4653090 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -318,7 +318,7 @@ The default cache stores provided include: everything into memory in the same process. If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances -won‘t be able to share cache data with each other. If your application never +won't be able to share cache data with each other. If your application never performs manual cache item expiry (e.g. when you‘re using generational cache keys), then using +MemoryStore+ is ok. Otherwise, consider carefully whether you should be using this cache store. @@ -490,13 +490,14 @@ h3. Advanced Caching Along with the built-in mechanisms outlined above, a number of excellent plugins exist to help with finer grained control over caching. These include -Chris Wanstrath's excellent cache_fu plugin (more info here: -http://errtheblog.com/posts/57-kickin-ass-w-cachefu) and Evan Weaver's -interlock plugin (more info here: -http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/). Both +Chris Wanstrath's excellent cache_fu plugin (more info "here": http://errtheblog.com/posts/57-kickin-ass-w-cachefu) and Evan Weaver's +interlock plugin (more info "here": http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/). Both of these plugins play nice with memcached and are a must-see for anyone seriously considering optimizing their caching needs. +Also the new "Cache money":http://github.com/nkallen/cache-money/tree/master plugin is supposed to be mad cool. + + h3. Changelog "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching -- cgit v1.2.3 From bb1ce5d199df115ddcc82b1b8dfafe14064fe031 Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Mon, 23 Feb 2009 17:21:23 -0500 Subject: Another strange character fix --- railties/guides/source/caching_with_rails.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 56d4653090..d978fabe82 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -433,7 +433,7 @@ Rails.cache.read("city") # => "Duckburgh" h3. Conditional GET support Conditional GETs are a facility of the HTTP spec that provide a way for web -servers to tell browsers that the response to a GET request hasn’t changed +servers to tell browsers that the response to a GET request hasn't changed since the last request and can be safely pulled from the browser cache. They work by using the HTTP_IF_NONE_MATCH and HTTP_IF_MODIFIED_SINCE headers to -- cgit v1.2.3 From 346ac0bba7cfbfbd0a7155163ca4125bc80ba463 Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Tue, 24 Feb 2009 00:30:02 -0500 Subject: Add references --- railties/guides/source/caching_with_rails.textile | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index d978fabe82..9736be8443 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -80,6 +80,8 @@ end If you want a more complicated expiration scheme, you can use cache sweepers to expire cached objects when things change. This is covered in the section on Sweepers. +Note: Page caching ignores all parameters, so /products/list?page=1 will be written out to the filesystem as /products/list.html and if someone requests /products/list?page=2, they will be returned the same result as page=1, so be careful when page caching GET parameters in the URL! + h4. Action Caching One of the issues with Page Caching is that you cannot use it for pages that @@ -497,6 +499,12 @@ seriously considering optimizing their caching needs. Also the new "Cache money":http://github.com/nkallen/cache-money/tree/master plugin is supposed to be mad cool. +h3. References + * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial + * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 + * "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html + * "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching + h3. Changelog "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching -- cgit v1.2.3 From c674d209e15237ff276be7513825139f578fe2d7 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 28 Feb 2009 19:40:34 +0000 Subject: Fix some formatting in the caching guide --- railties/guides/source/caching_with_rails.textile | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 9736be8443..b1c1af8be4 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -500,16 +500,17 @@ seriously considering optimizing their caching needs. Also the new "Cache money":http://github.com/nkallen/cache-money/tree/master plugin is supposed to be mad cool. h3. References - * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial - * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 - * "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html - * "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching +* "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial +* "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 +* "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html +* "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching h3. Changelog + "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching -February 22, 2009: Beefed up the section on cache_stores -December 27, 2008: Typo fixes -November 23, 2008: Incremental updates with various suggested changes and formatting cleanup -September 15, 2008: Initial version by Aditya Chadha +* February 22, 2009: Beefed up the section on cache_stores +* December 27, 2008: Typo fixes +* November 23, 2008: Incremental updates with various suggested changes and formatting cleanup +* September 15, 2008: Initial version by Aditya Chadha -- cgit v1.2.3 From 3f631a34285953d728e66ae2456ea1e7b1eb983c Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Sat, 14 Mar 2009 16:38:01 -0500 Subject: Some editorial cleanup on caching guide --- railties/guides/source/caching_with_rails.textile | 136 ++++++++++++---------- 1 file changed, 72 insertions(+), 64 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index b1c1af8be4..610bb9416e 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -4,6 +4,13 @@ Everyone caches. This guide will teach you what you need to know about avoiding that expensive round-trip to your database and returning what you need to return to those hungry web clients in the shortest time possible. +After reading this guide, you should be able to use and configure: + +* Page, action, and fragment caching +* Sweepers +* Alternative cache stores +* Conditional GET support + endprologue. h3. Basic Caching @@ -13,8 +20,7 @@ provides by default without the use of any third party plugins. To get started make sure +config.action_controller.perform_caching+ is set to +true+ for your environment. This flag is normally set in the -corresponding config/environments/*.rb and caching is disabled by default -there for development and test, and enabled for production. +corresponding config/environments/*.rb. By default, caching is disabled for development and test, and enabled for production. config.action_controller.perform_caching = true @@ -29,9 +35,9 @@ applied to every situation (such as pages that need authentication) and since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with. -So, how do you enable this super-fast cache behavior? Simple, let's say you -have a controller called ProductsController and a 'list' action that lists all -the products +So, how do you enable this super-fast cache behavior? Suppose you +have a controller called +ProductsController+ and an +index+ action that lists all +the products. You could enable caching for this action like this: class ProductsController < ActionController @@ -44,34 +50,33 @@ end The first time anyone requests products/index, Rails will generate a file -called +index.html+ and the webserver will then look for that file before it -passes the next request for products/index to your Rails application. +called +index.html+. If a web server see this file, it will be served in response to the +next request for products/index, without your Rails application being called. By default, the page cache directory is set to Rails.public_path (which is -usually set to +RAILS_ROOT + "/public"+) and this can be configured by +usually set to +File.join(self.root, "public")+ - that is, the public directory under your Rails application's root). This can be configured by changing the configuration setting +config.action_controller.page_cache_directory+. Changing the default from /public helps avoid naming conflicts, since you may want to put other static html in /public, but changing this will require web server reconfiguration to let the web server know where to serve the cached files from. -The Page Caching mechanism will automatically add a +.html+ extension to +The page caching mechanism will automatically add a +.html+ extension to requests for pages that do not have an extension to make it easy for the -webserver to find those pages and this can be configured by changing the +webserver to find those pages. This can be configured by changing the configuration setting +config.action_controller.page_cache_extension+. -In order to expire this page when a new product is added we could extend our -example controller like this: +In order to expire this page when a new product is added you could extend the products controller like this: class ProductsController < ActionController - caches_page :list + caches_page :index - def list; end + def index; end def create - expire_page :action => :list + expire_page :action => :index end end @@ -80,19 +85,19 @@ end If you want a more complicated expiration scheme, you can use cache sweepers to expire cached objects when things change. This is covered in the section on Sweepers. -Note: Page caching ignores all parameters, so /products/list?page=1 will be written out to the filesystem as /products/list.html and if someone requests /products/list?page=2, they will be returned the same result as page=1, so be careful when page caching GET parameters in the URL! +Note: Page caching ignores all parameters, so /products/list?page=1 will be written out to the filesystem as /products/list.html and if someone requests /products/list?page=2, they will be returned the same result as page=1. Be careful when page caching GET parameters in the URL! h4. Action Caching -One of the issues with Page Caching is that you cannot use it for pages that -require to restrict access somehow. This is where Action Caching comes in. -Action Caching works like Page Caching except for the fact that the incoming -web request does go from the webserver to the Rails stack and Action Pack so -that before filters can be run on it before the cache is served, so that -authentication and other restrictions can be used while still serving the +One of the issues with page caching is that you cannot use it for pages that +require checking code to determine whether the user should be permitted access. This is where Action Caching comes in. +action caching works like page caching except for the fact that the incoming +web request does go from the web server to the Rails stack and Action Pack so +that before filters can be run on it before the cache is served. This allows you to use +authentication and other restrictions while still serving the result of the output from a cached copy. -Clearing the cache works in the exact same way as with Page Caching. +Clearing the cache works in the exact same way as with page caching. Let's say you only wanted authenticated users to edit or create a Product object, but still cache those pages: @@ -101,13 +106,13 @@ object, but still cache those pages: class ProductsController < ActionController before_filter :authenticate, :only => [ :edit, :create ] - caches_page :list + caches_page :index caches_action :edit - def list; end + def index; end def create - expire_page :action => :list + expire_page :action => :index expire_action :action => :edit end @@ -116,19 +121,19 @@ class ProductsController < ActionController end -And you can also use +:if+ (or +:unless+) to pass a Proc that specifies when the +You can also use +:if+ (or +:unless+) to pass a Proc that specifies when the action should be cached. Also, you can use +:layout => false+ to cache without -layout so that dynamic information in the layout such as logged in user info +layout so that dynamic information in the layout such as the name of the logged-in user or the number of items in the cart can be left uncached. This feature is available as of Rails 2.2. You can modify the default action cache path by passing a +:cache_path+ option. -This will be passed directly to ActionCachePath.path_for. This is handy for +This will be passed directly to +ActionCachePath.path_for+. This is handy for actions with multiple possible routes that should be cached differently. If a block is given, it is called with the current controller instance. Finally, if you are using memcached, you can also pass +:expires_in+. In fact, -all parameters not used by caches_action are sent to the underlying cache +all parameters not used by +caches_action+ are sent to the underlying cache store. h4. Fragment Caching @@ -162,52 +167,56 @@ could use this piece of code: The cache block in our example will bind to the action that called it and is -written out to the same place as the Action Cache, which means that if you +written out to the same place as the action cache, which means that if you want to cache multiple fragments per action, you should provide an +action_suffix+ to the cache call: -<% cache(:action => 'recent', :action_suffix => 'all_products') do %> +<% cache(:action => 'recent', :action_suffix => 'all_prods') do %> All available products: -and you can expire it using the +expire_fragment+ method, like so: +You can expire the cache using the +expire_fragment+ method, like so: -expire_fragment(:controller => 'products', :action => 'recent', :action_suffix => 'all_products) +expire_fragment(:controller => 'products', :action => 'recent', + :action_suffix => 'all_prods) -If you don't want the cache block to bind to the action that called it, You can -also use globally keyed fragments by calling the cache method with a key, like +If you don't want the cache block to bind to the action that called it, you can +also use globally keyed fragments. To do this, call the +cache+ method with a key, like so: -<% cache(:key => ['all_available_products', @latest_product.created_at].join(':')) do %> +<% cache(:key => + ['all_available_products', @latest_product.created_at].join(':')) do %> All available products: <% end %> -This fragment is then available to all actions in the ProductsController using +This fragment is then available to all actions in the +ProductsController+ using the key and can be expired the same way: -expire_fragment(:key => ['all_available_products', @latest_product.created_at].join(':')) +expire_fragment(:key => + ['all_available_products', @latest_product.created_at].join(':')) h4. Sweepers Cache sweeping is a mechanism which allows you to get around having a ton of -expire_{page,action,fragment} calls in your code by moving all the work -required to expire cached content into a +ActionController::Caching::Sweeper+ -class that is an Observer and looks for changes to an object via callbacks, -and when a change occurs it expires the caches associated with that object n ++expire_{page,action,fragment}+ calls in your code. It does this by moving all the work +required to expire cached content into na +ActionController::Caching::Sweeper+ +class. This class is an Observer that looks for changes to an object via callbacks, +and when a change occurs it expires the caches associated with that object in an around or after filter. Continuing with our Product controller example, we could rewrite it with a -sweeper such as the following: +sweeper like this: class StoreSweeper < ActionController::Caching::Sweeper - observe Product # This sweeper is going to keep an eye on the Product model + # This sweeper is going to keep an eye on the Product model + observe Product # If our sweeper detects that a Product was created call this def after_create(product) @@ -230,13 +239,13 @@ class StoreSweeper < ActionController::Caching::Sweeper expire_page(:controller => '#{record}', :action => 'list') # Expire a fragment - expire_fragment(:controller => '#{record}', :action => 'recent', :action_suffix => 'all_products') + expire_fragment(:controller => '#{record}', + :action => 'recent', :action_suffix => 'all_products') end end -Then we add it to our controller to tell it to call the sweeper when certain -actions are called. So, if we wanted to expire the cached content for the +The sweeper has to be added to the controller that will use it. So, if we wanted to expire the cached content for the list and edit actions when the create action was called, we could do the following: @@ -263,9 +272,9 @@ end h4. SQL Caching Query caching is a Rails feature that caches the result set returned by each -query so that if Rails encounters the same query again for that request, it +query. If Rails encounters the same query again during the current request, it will used the cached result set as opposed to running the query against the -database again. +database. For example: @@ -306,7 +315,7 @@ that action and thus persist only for the duration of the action. h4. Cache stores -Rails (as of 2.1) provides different stores for the cached data for action and +Rails (as of 2.1) provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk. Rails 2.1 and above provide ActiveSupport::Cache::Store which can be used to @@ -314,7 +323,7 @@ cache strings. Some cache store implementations, like MemoryStore, are able to cache arbitrary Ruby objects, but don't count on every cache store to be able to do that. -The default cache stores provided include: +The default cache stores provided with Rails include: 1) ActiveSupport::Cache::MemoryStore: A cache store implementation which stores everything into memory in the same process. If you're running multiple Ruby on @@ -335,13 +344,12 @@ need thread-safety. ActionController::Base.cache_store = :memory_store -2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk, this is +2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk. This is the default store and the default path for this store is: /tmp/cache. Works well for all types of environments and allows all processes running from the same application directory to access the cached content. If /tmp/cache does not exist, the default store becomes MemoryStore. - ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" @@ -351,7 +359,6 @@ DRb process that all servers communicate with. This works for all environments and only keeps one cache around for all processes, but requires that you run and manage a separate DRb process. - ActionController::Base.cache_store = :drb_store, "druby://localhost:9192" @@ -361,27 +368,28 @@ Rails uses the bundled memcached-client gem by default. This is currently the most popular cache store for production websites. Special features: - * Clustering and load balancing. One can specify multiple memcached servers, + +* Clustering and load balancing. One can specify multiple memcached servers, and MemCacheStore will load balance between all available servers. If a server goes down, then MemCacheStore will ignore it until it goes back online. - * Time-based expiry support. See write and the +:expires_in+ option. - * Per-request in memory cache for all communication with the MemCache server(s). +* Time-based expiry support. See +write+ and the +:expires_in+ option. +* Per-request in memory cache for all communication with the MemCache server(s). It also accepts a hash of additional options: - * +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store. - * +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. - * +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. +* +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store. +* +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. +* +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. The read and write methods of the MemCacheStore accept an options hash too. When reading you can specify +:raw => true+ to prevent the object being marshaled (by default this is false which means the raw value in the cache is passed to -Marshal.load before being returned to you.) ++Marshal.load+ before being returned to you.) -When writing to the cache it is also possible to specify +:raw => true+ means -the value is not passed to Marshal.dump before being stored in the cache (by +When writing to the cache it is also possible to specify +:raw => true+. This means +that the value is not passed to +Marshal.dump+ before being stored in the cache (by default this is false). The write method also accepts an +:unless_exist+ flag which determines whether -- cgit v1.2.3 From 4216213f0610bddbb9f283fc5a2dfbfa9be75509 Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Sat, 14 Mar 2009 16:43:21 -0500 Subject: A few more changes for caching guide --- railties/guides/source/caching_with_rails.textile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 610bb9416e..691e21314c 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -424,11 +424,11 @@ ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost" ActionController::Base.cache_store = MyOwnStore.new("parameter") -+Note: config.cache_store can be used in place of -ActionController::Base.cache_store in your Rails::Initializer.run block in -environment.rb+ +NOTE: +config.cache_store+ can be used in place of ++ActionController::Base.cache_store+ in the +Rails::Initializer.run+ block in +environment.rb. -In addition to all of this, Rails also adds the ActiveRecord::Base#cache_key +In addition to all of this, Rails also adds the +ActiveRecord::Base#cache_key+ method that generates a key using the class name, id and updated_at timestamp (if available). @@ -442,7 +442,7 @@ Rails.cache.read("city") # => "Duckburgh" h3. Conditional GET support -Conditional GETs are a facility of the HTTP spec that provide a way for web +Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn't changed since the last request and can be safely pulled from the browser cache. -- cgit v1.2.3 From 1bd5a64f5ad30b0b8b018c52ba3d002c338b3c57 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sat, 14 Mar 2009 22:59:16 +0100 Subject: revised titles of caching guide --- railties/guides/source/caching_with_rails.textile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 691e21314c..5c55538283 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -313,7 +313,7 @@ database again the second time that finder is called. Query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action. -h4. Cache stores +h4. Cache Stores Rails (as of 2.1) provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk. @@ -440,7 +440,7 @@ Rails.cache.write("city", "Duckburgh") Rails.cache.read("city") # => "Duckburgh" -h3. Conditional GET support +h3. Conditional GET Support Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn't changed -- cgit v1.2.3 From e4ea27fd2d4751ce2d3164d0566994cc580347e9 Mon Sep 17 00:00:00 2001 From: Mike Gunderloy Date: Fri, 3 Apr 2009 08:15:41 -0500 Subject: Tech edit of caching guide from Gregg Pollack --- railties/guides/source/caching_with_rails.textile | 244 +++++++++++----------- 1 file changed, 120 insertions(+), 124 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 5c55538283..094753784f 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -2,7 +2,11 @@ h2. Caching with Rails: An overview Everyone caches. This guide will teach you what you need to know about avoiding that expensive round-trip to your database and returning what you -need to return to those hungry web clients in the shortest time possible. +need to return to those hungry web clients in the shortest time possible. + +If you prefer to watch screencasts to learn caching, Gregg Pollack produced +the "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails +which step you through everything detailed in this guide plus more. After reading this guide, you should be able to use and configure: @@ -18,9 +22,11 @@ h3. Basic Caching This is an introduction to the three types of caching techniques that Rails provides by default without the use of any third party plugins. -To get started make sure +config.action_controller.perform_caching+ is set -to +true+ for your environment. This flag is normally set in the -corresponding config/environments/*.rb. By default, caching is disabled for development and test, and enabled for production. +To start playing with testing you'll want to ensure that ++config.action_controller.perform_caching+ is set +to +true+ if you're running in development mode. This flag is normally set in the +corresponding config/environments/*.rb and caching is disabled by default + for development and test, and enabled for production. config.action_controller.perform_caching = true @@ -29,51 +35,56 @@ config.action_controller.perform_caching = true h4. Page Caching Page caching is a Rails mechanism which allows the request for a generated -page to be fulfilled by the webserver, without ever having to go through the +page to be fulfilled by the webserver (i.e. apache or nginx), without ever having to go through the Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be applied to every situation (such as pages that need authentication) and since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with. -So, how do you enable this super-fast cache behavior? Suppose you -have a controller called +ProductsController+ and an +index+ action that lists all -the products. You could enable caching for this action like this: +So, how do you enable this super-fast cache behavior? Simple, let's say you +have a controller called ProductsController and a 'list' action that lists all +the products class ProductsController < ActionController caches_page :index - def index; end + def index + @products = Products.all + end end The first time anyone requests products/index, Rails will generate a file -called +index.html+. If a web server see this file, it will be served in response to the -next request for products/index, without your Rails application being called. +called +index.html+ and the webserver will then look for that file before it +passes the next request for products/index to your Rails application. By default, the page cache directory is set to Rails.public_path (which is -usually set to +File.join(self.root, "public")+ - that is, the public directory under your Rails application's root). This can be configured by +usually set to "#{RAILS_ROOT}/public" and this can be configured by changing the configuration setting +config.action_controller.page_cache_directory+. Changing the default from /public helps avoid naming conflicts, since you may want to put other static html in /public, but changing this will require web server reconfiguration to let the web server know where to serve the cached files from. -The page caching mechanism will automatically add a +.html+ extension to +The Page Caching mechanism will automatically add a +.html+ extension to requests for pages that do not have an extension to make it easy for the -webserver to find those pages. This can be configured by changing the +webserver to find those pages and this can be configured by changing the configuration setting +config.action_controller.page_cache_extension+. -In order to expire this page when a new product is added you could extend the products controller like this: +In order to expire this page when a new product is added we could extend our +example controller like this: class ProductsController < ActionController caches_page :index - def index; end + def index + @products = Products.all + end def create expire_page :action => :index @@ -85,55 +96,52 @@ end If you want a more complicated expiration scheme, you can use cache sweepers to expire cached objects when things change. This is covered in the section on Sweepers. -Note: Page caching ignores all parameters, so /products/list?page=1 will be written out to the filesystem as /products/list.html and if someone requests /products/list?page=2, they will be returned the same result as page=1. Be careful when page caching GET parameters in the URL! +Note: Page caching ignores all parameters, so /products/list?page=1 will be written out to the filesystem as /products/list.html and if someone requests /products/list?page=2, they will be returned the same result as page=1, so be careful when page caching GET parameters in the URL! h4. Action Caching -One of the issues with page caching is that you cannot use it for pages that -require checking code to determine whether the user should be permitted access. This is where Action Caching comes in. -action caching works like page caching except for the fact that the incoming -web request does go from the web server to the Rails stack and Action Pack so -that before filters can be run on it before the cache is served. This allows you to use -authentication and other restrictions while still serving the +One of the issues with Page Caching is that you cannot use it for pages that +require to restrict access somehow. This is where Action Caching comes in. +Action Caching works like Page Caching except for the fact that the incoming +web request does go from the webserver to the Rails stack and Action Pack so +that before filters can be run on it before the cache is served. This allows +authentication and other restriction to be run while still serving the result of the output from a cached copy. -Clearing the cache works in the exact same way as with page caching. +Clearing the cache works in the exact same way as with Page Caching. -Let's say you only wanted authenticated users to edit or create a Product -object, but still cache those pages: +Let's say you only wanted authenticated users to call actions on the Products controller. class ProductsController < ActionController - before_filter :authenticate, :only => [ :edit, :create ] - caches_page :index - caches_action :edit + before_filter :authenticate + caches_action :index - def index; end + def index + @products = Product.all + end def create - expire_page :action => :index - expire_action :action => :edit + expire_action :action => :index end - def edit; end - end You can also use +:if+ (or +:unless+) to pass a Proc that specifies when the action should be cached. Also, you can use +:layout => false+ to cache without -layout so that dynamic information in the layout such as the name of the logged-in user +layout so that dynamic information in the layout such as logged in user info or the number of items in the cart can be left uncached. This feature is available as of Rails 2.2. You can modify the default action cache path by passing a +:cache_path+ option. -This will be passed directly to +ActionCachePath.path_for+. This is handy for +This will be passed directly to ActionCachePath.path_for. This is handy for actions with multiple possible routes that should be cached differently. If a block is given, it is called with the current controller instance. Finally, if you are using memcached, you can also pass +:expires_in+. In fact, -all parameters not used by +caches_action+ are sent to the underlying cache +all parameters not used by caches_action are sent to the underlying cache store. h4. Fragment Caching @@ -149,7 +157,7 @@ Fragment Caching allows a fragment of view logic to be wrapped in a cache block and served out of the cache store when the next request comes in. As an example, if you wanted to show all the orders placed on your website -in real time and didn't want to cache that part of the page, but did want +in real time and didn't want to cache that part of the page, but did want to cache the part of the page which lists all products available, you could use this piece of code: @@ -160,35 +168,33 @@ could use this piece of code: <% cache do %> All available products: - <% Product.find(:all).each do |p| %> + <% Product.all.each do |p| %> <%= link_to p.name, product_url(p) %> <% end %> <% end %> The cache block in our example will bind to the action that called it and is -written out to the same place as the action cache, which means that if you +written out to the same place as the Action Cache, which means that if you want to cache multiple fragments per action, you should provide an +action_suffix+ to the cache call: -<% cache(:action => 'recent', :action_suffix => 'all_prods') do %> +<% cache(:action => 'recent', :action_suffix => 'all_products') do %> All available products: -You can expire the cache using the +expire_fragment+ method, like so: +and you can expire it using the +expire_fragment+ method, like so: -expire_fragment(:controller => 'products', :action => 'recent', - :action_suffix => 'all_prods) +expire_fragment(:controller => 'products', :action => 'recent', :action_suffix => 'all_products') -If you don't want the cache block to bind to the action that called it, you can -also use globally keyed fragments. To do this, call the +cache+ method with a key, like +If you don't want the cache block to bind to the action that called it, You can +also use globally keyed fragments by calling the +cache+ method with a key, like so: -<% cache(:key => - ['all_available_products', @latest_product.created_at].join(':')) do %> +<% cache('all_available_products') do %> All available products: <% end %> @@ -197,16 +203,15 @@ This fragment is then available to all actions in the +ProductsController+ using the key and can be expired the same way: -expire_fragment(:key => - ['all_available_products', @latest_product.created_at].join(':')) +expire_fragment('all_available_products') h4. Sweepers Cache sweeping is a mechanism which allows you to get around having a ton of -+expire_{page,action,fragment}+ calls in your code. It does this by moving all the work -required to expire cached content into na +ActionController::Caching::Sweeper+ -class. This class is an Observer that looks for changes to an object via callbacks, ++expire_{page,action,fragment}+ calls in your code. It does this by moving all the work +required to expire cached content into a +ActionController::Caching::Sweeper+ +class. This class is an Observer and looks for changes to an object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter. @@ -214,9 +219,8 @@ Continuing with our Product controller example, we could rewrite it with a sweeper like this: -class StoreSweeper < ActionController::Caching::Sweeper - # This sweeper is going to keep an eye on the Product model - observe Product +class ProductSweeper < ActionController::Caching::Sweeper + observe Product # This sweeper is going to keep an eye on the Product model # If our sweeper detects that a Product was created call this def after_create(product) @@ -234,91 +238,82 @@ class StoreSweeper < ActionController::Caching::Sweeper end private - def expire_cache_for(record) - # Expire the list page now that we added a new product - expire_page(:controller => '#{record}', :action => 'list') + def expire_cache_for(product) + # Expire the index page now that we added a new product + expire_page(:controller => 'products', :action => 'index') # Expire a fragment - expire_fragment(:controller => '#{record}', - :action => 'recent', :action_suffix => 'all_products') + expire_fragment('all_available_products') end end -The sweeper has to be added to the controller that will use it. So, if we wanted to expire the cached content for the +You may notice that the actual product gets passed to the sweeper, so if we +were caching the edit action for each product, we could add a expire method +which specifies the page we want to expire: + + + expire_action(:controller => 'products', :action => 'edit', :id => product) + + +Then we add it to our controller to tell it to call the sweeper when certain +actions are called. So, if we wanted to expire the cached content for the list and edit actions when the create action was called, we could do the following: class ProductsController < ActionController - before_filter :authenticate, :only => [ :edit, :create ] - caches_page :list - caches_action :edit - cache_sweeper :store_sweeper, :only => [ :create ] - - def list; end + before_filter :authenticate + caches_action :index + cache_sweeper :product_sweeper - def create - expire_page :action => :list - expire_action :action => :edit + def index + @products = Product.all end - def edit; end - end h4. SQL Caching Query caching is a Rails feature that caches the result set returned by each -query. If Rails encounters the same query again during the current request, it +query so that if Rails encounters the same query again for that request, it will used the cached result set as opposed to running the query against the -database. +database again. For example: class ProductsController < ActionController - before_filter :authenticate, :only => [ :edit, :create ] - caches_page :list - caches_action :edit - cache_sweeper :store_sweeper, :only => [ :create ] - - def list + def index # Run a find query - Product.find(:all) + @products = Product.all ... # Run the same query again - Product.find(:all) - end - - def create - expire_page :action => :list - expire_action :action => :edit + @products = Product.all end - def edit; end - end -In the 'list' action above, the result set returned by the first -Product.find(:all) will be cached and will be used to avoid querying the -database again the second time that finder is called. +The second time the same query is run against the database, it's not actually +going to hit the database. The first time the result is returned from the query +it is stored in the query cache (in memory) and the second time it's pulled from memory. -Query caches are created at the start of an action and destroyed at the end of -that action and thus persist only for the duration of the action. +However, it's important to note that query caches are created at the start of an action and destroyed at the end of +that action and thus persist only for the duration of the action. If you'd like to store query results in a more +persistent fashion, you can in Rails by using low level caching. -h4. Cache Stores +h4. Cache stores Rails (as of 2.1) provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk. -Rails 2.1 and above provide ActiveSupport::Cache::Store which can be used to +Rails 2.1 and above provide +ActiveSupport::Cache::Store+ which can be used to cache strings. Some cache store implementations, like MemoryStore, are able to cache arbitrary Ruby objects, but don't count on every cache store to be able to do that. @@ -344,12 +339,13 @@ need thread-safety. ActionController::Base.cache_store = :memory_store -2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk. This is +2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk, this is the default store and the default path for this store is: /tmp/cache. Works well for all types of environments and allows all processes running from the same application directory to access the cached content. If /tmp/cache does not exist, the default store becomes MemoryStore. + ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" @@ -359,6 +355,7 @@ DRb process that all servers communicate with. This works for all environments and only keeps one cache around for all processes, but requires that you run and manage a separate DRb process. + ActionController::Base.cache_store = :drb_store, "druby://localhost:9192" @@ -368,28 +365,26 @@ Rails uses the bundled memcached-client gem by default. This is currently the most popular cache store for production websites. Special features: - -* Clustering and load balancing. One can specify multiple memcached servers, + * Clustering and load balancing. One can specify multiple memcached servers, and MemCacheStore will load balance between all available servers. If a server goes down, then MemCacheStore will ignore it until it goes back online. -* Time-based expiry support. See +write+ and the +:expires_in+ option. -* Per-request in memory cache for all communication with the MemCache server(s). + * Time-based expiry support. See +write+ and the +:expires_in+ option. + * Per-request in memory cache for all communication with the MemCache server(s). It also accepts a hash of additional options: -* +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store. -* +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. -* +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. + * +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store. + * +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. + * +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. The read and write methods of the MemCacheStore accept an options hash too. -When reading you can specify +:raw => true+ to prevent the object being -marshaled +When reading you can specify +:raw => true+ to prevent the object being marshaled (by default this is false which means the raw value in the cache is passed to +Marshal.load+ before being returned to you.) -When writing to the cache it is also possible to specify +:raw => true+. This means -that the value is not passed to +Marshal.dump+ before being stored in the cache (by +When writing to the cache it is also possible to specify +:raw => true+ means +the value is not passed to +Marshal.dump+ before being stored in the cache (by default this is false). The write method also accepts an +:unless_exist+ flag which determines whether @@ -424,15 +419,15 @@ ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost" ActionController::Base.cache_store = MyOwnStore.new("parameter") -NOTE: +config.cache_store+ can be used in place of -+ActionController::Base.cache_store+ in the +Rails::Initializer.run+ block in -environment.rb. ++Note: config.cache_store can be used in place of +ActionController::Base.cache_store in your Rails::Initializer.run block in +environment.rb+ -In addition to all of this, Rails also adds the +ActiveRecord::Base#cache_key+ +In addition to all of this, Rails also adds the ActiveRecord::Base#cache_key method that generates a key using the class name, id and updated_at timestamp (if available). -An example: +You can access these cache stores at a low level for storing queries and other objects. Here's an example: Rails.cache.read("city") # => nil @@ -440,7 +435,7 @@ Rails.cache.write("city", "Duckburgh") Rails.cache.read("city") # => "Duckburgh" -h3. Conditional GET Support +h3. Conditional GET support Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn't changed @@ -508,17 +503,18 @@ seriously considering optimizing their caching needs. Also the new "Cache money":http://github.com/nkallen/cache-money/tree/master plugin is supposed to be mad cool. h3. References + * "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails + * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial + * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 + * "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html + * "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching -* "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial -* "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 -* "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html -* "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching h3. Changelog - "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching -* February 22, 2009: Beefed up the section on cache_stores -* December 27, 2008: Typo fixes -* November 23, 2008: Incremental updates with various suggested changes and formatting cleanup -* September 15, 2008: Initial version by Aditya Chadha +April 1, 2009: Made a bunch of small fixes +February 22, 2009: Beefed up the section on cache_stores +December 27, 2008: Typo fixes +November 23, 2008: Incremental updates with various suggested changes and formatting cleanup +September 15, 2008: Initial version by Aditya Chadha -- cgit v1.2.3 From 2e601d8da7cdd0712526dbf1c1346f6e19830538 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 3 Apr 2009 15:50:55 +0200 Subject: in caching guide, RESTifies some examples, revised conventions here and there --- railties/guides/source/caching_with_rails.textile | 49 +++++++++++------------ 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 094753784f..10392ba6c6 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -42,7 +42,7 @@ the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with. So, how do you enable this super-fast cache behavior? Simple, let's say you -have a controller called ProductsController and a 'list' action that lists all +have a controller called +ProductsController+ and a +list+ action that lists all the products @@ -57,15 +57,15 @@ class ProductsController < ActionController end -The first time anyone requests products/index, Rails will generate a file -called +index.html+ and the webserver will then look for that file before it -passes the next request for products/index to your Rails application. +The first time anyone requests +/products+, Rails will generate a file +called +products.html+ and the webserver will then look for that file before it +passes the next request for +/products+ to your Rails application. -By default, the page cache directory is set to Rails.public_path (which is -usually set to "#{RAILS_ROOT}/public" and this can be configured by +By default, the page cache directory is set to +Rails.public_path+ (which is +usually set to the +public+ folder) and this can be configured by changing the configuration setting +config.action_controller.page_cache_directory+. -Changing the default from /public helps avoid naming conflicts, since you may -want to put other static html in /public, but changing this will require web +Changing the default from +public+ helps avoid naming conflicts, since you may +want to put other static html in +public+, but changing this will require web server reconfiguration to let the web server know where to serve the cached files from. @@ -96,7 +96,7 @@ end If you want a more complicated expiration scheme, you can use cache sweepers to expire cached objects when things change. This is covered in the section on Sweepers. -Note: Page caching ignores all parameters, so /products/list?page=1 will be written out to the filesystem as /products/list.html and if someone requests /products/list?page=2, they will be returned the same result as page=1, so be careful when page caching GET parameters in the URL! +Note: Page caching ignores all parameters. For example +/products?page=1+ will be written out to the filesystem as +products.html+ with no reference to the +page+ parameter. Thus, if someone requests +/products?page=2+ later, they will get the cached first page. Be careful when page caching GET parameters in the URL! h4. Action Caching @@ -110,7 +110,7 @@ result of the output from a cached copy. Clearing the cache works in the exact same way as with Page Caching. -Let's say you only wanted authenticated users to call actions on the Products controller. +Let's say you only wanted authenticated users to call actions on +ProductsController+. class ProductsController < ActionController @@ -136,12 +136,12 @@ or the number of items in the cart can be left uncached. This feature is available as of Rails 2.2. You can modify the default action cache path by passing a +:cache_path+ option. -This will be passed directly to ActionCachePath.path_for. This is handy for +This will be passed directly to +ActionCachePath.path_for+. This is handy for actions with multiple possible routes that should be cached differently. If a block is given, it is called with the current controller instance. Finally, if you are using memcached, you can also pass +:expires_in+. In fact, -all parameters not used by caches_action are sent to the underlying cache +all parameters not used by +caches_action+ are sent to the underlying cache store. h4. Fragment Caching @@ -419,15 +419,14 @@ ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost" ActionController::Base.cache_store = MyOwnStore.new("parameter") -+Note: config.cache_store can be used in place of -ActionController::Base.cache_store in your Rails::Initializer.run block in -environment.rb+ ++Note: +config.cache_store+ can be used in place of ++ActionController::Base.cache_store+ in your +Rails::Initializer.run+ block in ++environment.rb+ -In addition to all of this, Rails also adds the ActiveRecord::Base#cache_key -method that generates a key using the class name, id and updated_at timestamp -(if available). +In addition to all of this, Rails also adds the +ActiveRecord::Base#cache_key+ +method that generates a key using the class name, +id+ and +updated_at+ timestamp (if available). -You can access these cache stores at a low level for storing queries and other objects. Here's an example: +You can access these cache stores at a low level for storing queries and other objects. Here's an example: Rails.cache.read("city") # => nil @@ -441,12 +440,12 @@ Conditional GETs are a feature of the HTTP specification that provide a way for servers to tell browsers that the response to a GET request hasn't changed since the last request and can be safely pulled from the browser cache. -They work by using the HTTP_IF_NONE_MATCH and HTTP_IF_MODIFIED_SINCE headers to -pass back and forth both a unique content identifier and the timestamp of when -the content was last changed. If the browser makes a request where the content -identifier (etag) or last modified since timestamp matches the server’s version -then the server only needs to send back an empty response with a not modified -status. +They work by using the +HTTP_IF_NONE_MATCH+ and +HTTP_IF_MODIFIED_SINCE+ headers +to pass back and forth both a unique content identifier and the timestamp of +when the content was last changed. If the browser makes a request where the +content identifier (etag) or last modified since timestamp matches the server’s +version then the server only needs to send back an empty response with a not +modified status. It is the server's (i.e. our) responsibility to look for a last modified timestamp and the if-none-match header and determine whether or not to send -- cgit v1.2.3 From 9488d583eea3b1301761afc5229c6d2e8caffd0d Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 3 Apr 2009 15:52:16 +0200 Subject: list -> index --- railties/guides/source/caching_with_rails.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 10392ba6c6..5adb27b0fe 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -42,7 +42,7 @@ the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with. So, how do you enable this super-fast cache behavior? Simple, let's say you -have a controller called +ProductsController+ and a +list+ action that lists all +have a controller called +ProductsController+ and an +index+ action that lists all the products -- cgit v1.2.3 From a7e757f8af81cf60658d944bf7611a563699b6c6 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Fri, 3 Apr 2009 23:32:16 +0200 Subject: deletes screencast promo in prologue, its proper place is the References section --- railties/guides/source/caching_with_rails.textile | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 5adb27b0fe..dd1b76bbc4 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -4,10 +4,6 @@ Everyone caches. This guide will teach you what you need to know about avoiding that expensive round-trip to your database and returning what you need to return to those hungry web clients in the shortest time possible. -If you prefer to watch screencasts to learn caching, Gregg Pollack produced -the "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails -which step you through everything detailed in this guide plus more. - After reading this guide, you should be able to use and configure: * Page, action, and fragment caching @@ -502,11 +498,12 @@ seriously considering optimizing their caching needs. Also the new "Cache money":http://github.com/nkallen/cache-money/tree/master plugin is supposed to be mad cool. h3. References - * "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails - * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial - * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 - * "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html - * "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching + +* "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails +* "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial +* "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 +* "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html +* "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching h3. Changelog -- cgit v1.2.3 From 4d1e21e8cbfa1bca4387714b684fdb4daddb673a Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Sun, 26 Apr 2009 23:07:40 -0400 Subject: Fix typos in submitted patch --- railties/guides/source/caching_with_rails.textile | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index f1ad7b820d..3df65018e8 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -44,9 +44,9 @@ the products class ProductsController < ActionController - caches_page :index + caches_page :list - def index + def list @products = Products.all end @@ -76,14 +76,14 @@ example controller like this: class ProductsController < ActionController - caches_page :index + caches_page :list - def index + def list @products = Products.all end def create - expire_page :action => :index + expire_page :action => :list end end @@ -275,7 +275,7 @@ h4. SQL Caching Query caching is a Rails feature that caches the result set returned by each query so that if Rails encounters the same query again for that request, it -will used the cached result set as opposed to running the query against the +will use the cached result set as opposed to running the query against the database again. For example: @@ -481,7 +481,7 @@ class ProductsController < ApplicationController def show @product = Product.find(params[:id]) - fresh_when :last_modified => @product.published_at.utc, :etag => @article + fresh_when :last_modified => @product.published_at.utc, :etag => @product end end @@ -501,7 +501,7 @@ h3. References * "Scaling Rails Screencasts":http://railslab.newrelic.com/scaling-rails * "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/2/28/rails-caching-tutorial -* "RailsEnvy, Rails Caching Tutorial, Part 1":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 +* "RailsEnvy, Rails Caching Tutorial, Part 2":http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2 * "ActiveSupport::Cache documentation":http://api.rubyonrails.org/classes/ActiveSupport/Cache.html * "Rails 2.1 integrated caching tutorial":http://thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching @@ -509,6 +509,7 @@ h3. References h3. Changelog "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching +April 26, 2009: Clean up typos in submitted patch April 1, 2009: Made a bunch of small fixes February 22, 2009: Beefed up the section on cache_stores December 27, 2008: Typo fixes -- cgit v1.2.3 From e5bebbbeffcb8b7912b67a6ebd893342d450a130 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Mon, 27 Apr 2009 10:18:37 +0200 Subject: bring index actions back in caching guide, REST conventions are encouraged and surrounding text assumes index --- railties/guides/source/caching_with_rails.textile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 3df65018e8..3b0c43d6ee 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -44,9 +44,9 @@ the products class ProductsController < ActionController - caches_page :list + caches_page :index - def list + def index @products = Products.all end @@ -76,9 +76,9 @@ example controller like this: class ProductsController < ActionController - caches_page :list + caches_page :index - def list + def index @products = Products.all end -- cgit v1.2.3 From eeb12d6ad5c24e65f63029f517e23fc5e02a617c Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Mon, 27 Apr 2009 22:01:22 -0400 Subject: Formatting updates per lifo --- railties/guides/source/caching_with_rails.textile | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 3df65018e8..08377f2456 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -304,7 +304,7 @@ However, it's important to note that query caches are created at the start of an that action and thus persist only for the duration of the action. If you'd like to store query results in a more persistent fashion, you can in Rails by using low level caching. -h4. Cache stores +h3. Cache stores Rails (as of 2.1) provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk. @@ -316,7 +316,7 @@ to do that. The default cache stores provided with Rails include: -1) ActiveSupport::Cache::MemoryStore: A cache store implementation which stores +# ActiveSupport::Cache::MemoryStore: A cache store implementation which stores everything into memory in the same process. If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances @@ -325,17 +325,15 @@ performs manual cache item expiry (e.g. when you‘re using generational cache keys), then using +MemoryStore+ is ok. Otherwise, consider carefully whether you should be using this cache store. -+MemoryStore+ is not only able to store strings, but also arbitrary Ruby objects. ++MemoryStore+ is not only able to store strings, but also arbitrary Ruby objects. -+MemoryStore+ is not thread-safe. Use +SynchronizedMemoryStore+ instead if you -need thread-safety. ++MemoryStore+ is not thread-safe. Use +SynchronizedMemoryStore+ instead if you need thread-safety. - ActionController::Base.cache_store = :memory_store -2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk, this is +# ActiveSupport::Cache::FileStore: Cached data is stored on the disk, this is the default store and the default path for this store is: /tmp/cache. Works well for all types of environments and allows all processes running from the same application directory to access the cached content. If /tmp/cache does not @@ -346,7 +344,7 @@ exist, the default store becomes MemoryStore. ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" -3) ActiveSupport::Cache::DRbStore: Cached data is stored in a separate shared +# ActiveSupport::Cache::DRbStore: Cached data is stored in a separate shared DRb process that all servers communicate with. This works for all environments and only keeps one cache around for all processes, but requires that you run and manage a separate DRb process. @@ -356,7 +354,7 @@ and manage a separate DRb process. ActionController::Base.cache_store = :drb_store, "druby://localhost:9192" -4) MemCached store: Works like DRbStore, but uses Danga's MemCache instead. +# MemCached store: Works like DRbStore, but uses Danga's MemCache instead. Rails uses the bundled memcached-client gem by default. This is currently the most popular cache store for production websites. @@ -393,14 +391,14 @@ for the cached item in seconds. ActionController::Base.cache_store = :mem_cache_store, "localhost" -5) ActiveSupport::Cache::SynchronizedMemoryStore: Like ActiveSupport::Cache::MemoryStore but thread-safe. +# ActiveSupport::Cache::SynchronizedMemoryStore: Like ActiveSupport::Cache::MemoryStore but thread-safe. ActionController::Base.cache_store = :synchronized_memory_store -6) ActiveSupport::Cache::CompressedMemCacheStore: Works just like the regular +# ActiveSupport::Cache::CompressedMemCacheStore: Works just like the regular MemCacheStore but uses GZip to decompress/compress on read/write. @@ -408,7 +406,7 @@ MemCacheStore but uses GZip to decompress/compress on read/write. ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost" -7) Custom store: You can define your own cache store (new in Rails 2.1) +# Custom store: You can define your own cache store (new in Rails 2.1) -- cgit v1.2.3 From 5469a0be1a517a0c2d8ee553b704df4e6f7df306 Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Sat, 2 May 2009 18:32:35 -0400 Subject: Formatting fixes --- railties/guides/source/caching_with_rails.textile | 38 +++++++++++++++-------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 9658927a36..d38d3a9949 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -316,7 +316,7 @@ to do that. The default cache stores provided with Rails include: -# ActiveSupport::Cache::MemoryStore: A cache store implementation which stores +1) ActiveSupport::Cache::MemoryStore: A cache store implementation which stores everything into memory in the same process. If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances @@ -333,7 +333,7 @@ should be using this cache store. ActionController::Base.cache_store = :memory_store -# ActiveSupport::Cache::FileStore: Cached data is stored on the disk, this is +2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk, this is the default store and the default path for this store is: /tmp/cache. Works well for all types of environments and allows all processes running from the same application directory to access the cached content. If /tmp/cache does not @@ -344,7 +344,7 @@ exist, the default store becomes MemoryStore. ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" -# ActiveSupport::Cache::DRbStore: Cached data is stored in a separate shared +3) ActiveSupport::Cache::DRbStore: Cached data is stored in a separate shared DRb process that all servers communicate with. This works for all environments and only keeps one cache around for all processes, but requires that you run and manage a separate DRb process. @@ -354,23 +354,28 @@ and manage a separate DRb process. ActionController::Base.cache_store = :drb_store, "druby://localhost:9192" -# MemCached store: Works like DRbStore, but uses Danga's MemCache instead. +4) MemCached store: Works like DRbStore, but uses Danga's MemCache instead. Rails uses the bundled memcached-client gem by default. This is currently the most popular cache store for production websites. Special features: - * Clustering and load balancing. One can specify multiple memcached servers, + +* Clustering and load balancing. One can specify multiple memcached servers, and MemCacheStore will load balance between all available servers. If a server goes down, then MemCacheStore will ignore it until it goes back online. - * Time-based expiry support. See +write+ and the +:expires_in+ option. - * Per-request in memory cache for all communication with the MemCache server(s). + +* Time-based expiry support. See +write+ and the +:expires_in+ option. + +* Per-request in memory cache for all communication with the MemCache server(s). It also accepts a hash of additional options: - * +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store. - * +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. - * +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. +* +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store. + +* +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. + +* +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. The read and write methods of the MemCacheStore accept an options hash too. When reading you can specify +:raw => true+ to prevent the object being marshaled @@ -391,14 +396,14 @@ for the cached item in seconds. ActionController::Base.cache_store = :mem_cache_store, "localhost" -# ActiveSupport::Cache::SynchronizedMemoryStore: Like ActiveSupport::Cache::MemoryStore but thread-safe. +5) ActiveSupport::Cache::SynchronizedMemoryStore: Like ActiveSupport::Cache::MemoryStore but thread-safe. ActionController::Base.cache_store = :synchronized_memory_store -# ActiveSupport::Cache::CompressedMemCacheStore: Works just like the regular +6) ActiveSupport::Cache::CompressedMemCacheStore: Works just like the regular MemCacheStore but uses GZip to decompress/compress on read/write. @@ -406,7 +411,7 @@ MemCacheStore but uses GZip to decompress/compress on read/write. ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost" -# Custom store: You can define your own cache store (new in Rails 2.1) +7) Custom store: You can define your own cache store (new in Rails 2.1) @@ -507,9 +512,16 @@ h3. References h3. Changelog "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching +May 02, 2009: Formatting cleanups + April 26, 2009: Clean up typos in submitted patch + April 1, 2009: Made a bunch of small fixes + February 22, 2009: Beefed up the section on cache_stores + December 27, 2008: Typo fixes + November 23, 2008: Incremental updates with various suggested changes and formatting cleanup + September 15, 2008: Initial version by Aditya Chadha -- cgit v1.2.3 From 8f3a3c5544401c2e69f7354644420258caa4e8c2 Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Sat, 2 May 2009 18:36:13 -0400 Subject: Formatting fixes, take 2 --- railties/guides/source/caching_with_rails.textile | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index d38d3a9949..9fd8b8a1fe 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -360,21 +360,14 @@ most popular cache store for production websites. Special features: -* Clustering and load balancing. One can specify multiple memcached servers, - and MemCacheStore will load balance between all available servers. If a - server goes down, then MemCacheStore will ignore it until it goes back - online. - +* Clustering and load balancing. One can specify multiple memcached servers, and MemCacheStore will load balance between all available servers. If a server goes down, then MemCacheStore will ignore it until it goes back online. * Time-based expiry support. See +write+ and the +:expires_in+ option. - * Per-request in memory cache for all communication with the MemCache server(s). It also accepts a hash of additional options: * +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store. - * +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. - * +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. The read and write methods of the MemCacheStore accept an options hash too. -- cgit v1.2.3 From 80e161e647a504c89c64358cf2644ad18a3ba85e Mon Sep 17 00:00:00 2001 From: Aditya Chadha Date: Sat, 2 May 2009 18:37:15 -0400 Subject: Formatting fixes, take 3 --- railties/guides/source/caching_with_rails.textile | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 9fd8b8a1fe..2ad3067ed0 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -505,16 +505,10 @@ h3. References h3. Changelog "Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching -May 02, 2009: Formatting cleanups - -April 26, 2009: Clean up typos in submitted patch - -April 1, 2009: Made a bunch of small fixes - -February 22, 2009: Beefed up the section on cache_stores - -December 27, 2008: Typo fixes - -November 23, 2008: Incremental updates with various suggested changes and formatting cleanup - -September 15, 2008: Initial version by Aditya Chadha +* May 02, 2009: Formatting cleanups +* April 26, 2009: Clean up typos in submitted patch +* April 1, 2009: Made a bunch of small fixes +* February 22, 2009: Beefed up the section on cache_stores +* December 27, 2008: Typo fixes +* November 23, 2008: Incremental updates with various suggested changes and formatting cleanup +* September 15, 2008: Initial version by Aditya Chadha -- cgit v1.2.3 From a65224f0367d4b4fe06d14df8e4481eacd5380ce Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 13 May 2009 23:29:33 +0200 Subject: a few details in the caching guide I saw in passing --- railties/guides/source/caching_with_rails.textile | 48 +++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 2ad3067ed0..ef2e6fb6eb 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -304,19 +304,19 @@ However, it's important to note that query caches are created at the start of an that action and thus persist only for the duration of the action. If you'd like to store query results in a more persistent fashion, you can in Rails by using low level caching. -h3. Cache stores +h3. Cache Stores Rails (as of 2.1) provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk. Rails 2.1 and above provide +ActiveSupport::Cache::Store+ which can be used to -cache strings. Some cache store implementations, like MemoryStore, are able to +cache strings. Some cache store implementations, like +MemoryStore+, are able to cache arbitrary Ruby objects, but don't count on every cache store to be able to do that. The default cache stores provided with Rails include: -1) ActiveSupport::Cache::MemoryStore: A cache store implementation which stores +1) +ActiveSupport::Cache::MemoryStore+: A cache store implementation which stores everything into memory in the same process. If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances @@ -333,18 +333,18 @@ should be using this cache store. ActionController::Base.cache_store = :memory_store -2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk, this is -the default store and the default path for this store is: /tmp/cache. Works +2) +ActiveSupport::Cache::FileStore+: Cached data is stored on the disk, this is +the default store and the default path for this store is +tmp/cache+. Works well for all types of environments and allows all processes running from the -same application directory to access the cached content. If /tmp/cache does not -exist, the default store becomes MemoryStore. +same application directory to access the cached content. If +tmp/cache+ does not +exist, the default store becomes +MemoryStore+. ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" -3) ActiveSupport::Cache::DRbStore: Cached data is stored in a separate shared +3) +ActiveSupport::Cache::DRbStore+: Cached data is stored in a separate shared DRb process that all servers communicate with. This works for all environments and only keeps one cache around for all processes, but requires that you run and manage a separate DRb process. @@ -354,23 +354,25 @@ and manage a separate DRb process. ActionController::Base.cache_store = :drb_store, "druby://localhost:9192" -4) MemCached store: Works like DRbStore, but uses Danga's MemCache instead. -Rails uses the bundled memcached-client gem by default. This is currently the -most popular cache store for production websites. +4) +ActiveSupport::Cache::MemCacheStore+: Works like +DRbStore+, +but uses Danga's +memcached+ instead. Rails uses the bundled +memcached-client+ gem by +default. This is currently the most popular cache store for production websites. Special features: -* Clustering and load balancing. One can specify multiple memcached servers, and MemCacheStore will load balance between all available servers. If a server goes down, then MemCacheStore will ignore it until it goes back online. +* Clustering and load balancing. One can specify multiple memcached servers, and ++MemCacheStore+ will load balance between all available servers. If a server goes +down, then +MemCacheStore+ will ignore it until it goes back online. * Time-based expiry support. See +write+ and the +:expires_in+ option. -* Per-request in memory cache for all communication with the MemCache server(s). +* Per-request in memory cache for all communication with the +memcached+ server(s). It also accepts a hash of additional options: -* +:namespace+- specifies a string that will automatically be prepended to keys when accessing the memcached store. -* +:readonly+- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. -* +:multithread+ - a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. +* +:namespace+: specifies a string that will automatically be prepended to keys when accessing the memcached store. +* +:readonly+: a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. +* +:multithread+: a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. -The read and write methods of the MemCacheStore accept an options hash too. +The read and write methods of the +MemCacheStore+ accept an options hash too. When reading you can specify +:raw => true+ to prevent the object being marshaled (by default this is false which means the raw value in the cache is passed to +Marshal.load+ before being returned to you.) @@ -389,31 +391,29 @@ for the cached item in seconds. ActionController::Base.cache_store = :mem_cache_store, "localhost" -5) ActiveSupport::Cache::SynchronizedMemoryStore: Like ActiveSupport::Cache::MemoryStore but thread-safe. +5) +ActiveSupport::Cache::SynchronizedMemoryStore+: Like +MemoryStore+ but thread-safe. ActionController::Base.cache_store = :synchronized_memory_store -6) ActiveSupport::Cache::CompressedMemCacheStore: Works just like the regular -MemCacheStore but uses GZip to decompress/compress on read/write. +6) +ActiveSupport::Cache::CompressedMemCacheStore+: Works just like the regular ++MemCacheStore+ but uses GZip to decompress/compress on read/write. ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost" -7) Custom store: You can define your own cache store (new in Rails 2.1) +7) Custom store: You can define your own cache store (new in Rails 2.1). ActionController::Base.cache_store = MyOwnStore.new("parameter") -+Note: +config.cache_store+ can be used in place of -+ActionController::Base.cache_store+ in your +Rails::Initializer.run+ block in -+environment.rb+ +NOTE: +config.cache_store+ can be used in place of +ActionController::Base.cache_store+ in your +Rails::Initializer.run+ block in +environment.rb+ In addition to all of this, Rails also adds the +ActiveRecord::Base#cache_key+ method that generates a key using the class name, +id+ and +updated_at+ timestamp (if available). -- cgit v1.2.3 From c8fb22bc2933beb5c6cc4113380c8faf77d87ffe Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sat, 16 May 2009 16:47:24 +0200 Subject: Remove some informal sentences and new lines --- railties/guides/source/caching_with_rails.textile | 216 +++++----------------- 1 file changed, 44 insertions(+), 172 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index ef2e6fb6eb..6d8c51355b 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -1,8 +1,6 @@ h2. Caching with Rails: An overview -Everyone caches. This guide will teach you what you need to know about -avoiding that expensive round-trip to your database and returning what you -need to return to those hungry web clients in the shortest time possible. +This guide will teach you what you need to know about avoiding that expensive round-trip to your database and returning what you need to return to the web clients in the shortest time possible. After reading this guide, you should be able to use and configure: @@ -15,14 +13,9 @@ endprologue. h3. Basic Caching -This is an introduction to the three types of caching techniques that Rails -provides by default without the use of any third party plugins. +This is an introduction to the three types of caching techniques that Rails provides by default without the use of any third party plugins. -To start playing with testing you'll want to ensure that -+config.action_controller.perform_caching+ is set -to +true+ if you're running in development mode. This flag is normally set in the -corresponding config/environments/*.rb and caching is disabled by default - for development and test, and enabled for production. +To start playing with testing you'll want to ensure that +config.action_controller.perform_caching+ is set to +true+ if you're running in development mode. This flag is normally set in the corresponding +config/environments/*.rb+ and caching is disabled by default for development and test, and enabled for production. config.action_controller.perform_caching = true @@ -30,16 +23,9 @@ config.action_controller.perform_caching = true h4. Page Caching -Page caching is a Rails mechanism which allows the request for a generated -page to be fulfilled by the webserver (i.e. apache or nginx), without ever having to go through the -Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be -applied to every situation (such as pages that need authentication) and since -the webserver is literally just serving a file from the filesystem, cache -expiration is an issue that needs to be dealt with. +Page caching is a Rails mechanism which allows the request for a generated page to be fulfilled by the webserver (i.e. apache or nginx), without ever having to go through the Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be applied to every situation (such as pages that need authentication) and since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with. -So, how do you enable this super-fast cache behavior? Simple, let's say you -have a controller called +ProductsController+ and an +index+ action that lists all -the products +So, how do you enable this super-fast cache behavior? Simple, let's say you have a controller called +ProductsController+ and an +index+ action that lists all the products class ProductsController < ActionController @@ -53,25 +39,13 @@ class ProductsController < ActionController end -The first time anyone requests +/products+, Rails will generate a file -called +products.html+ and the webserver will then look for that file before it -passes the next request for +/products+ to your Rails application. +The first time anyone requests +/products+, Rails will generate a file called +products.html+ and the webserver will then look for that file before it passes the next request for +/products+ to your Rails application. -By default, the page cache directory is set to +Rails.public_path+ (which is -usually set to the +public+ folder) and this can be configured by -changing the configuration setting +config.action_controller.page_cache_directory+. -Changing the default from +public+ helps avoid naming conflicts, since you may -want to put other static html in +public+, but changing this will require web -server reconfiguration to let the web server know where to serve the cached -files from. +By default, the page cache directory is set to +Rails.public_path+ (which is usually set to the +public+ folder) and this can be configured by changing the configuration setting +config.action_controller.page_cache_directory+. Changing the default from +public+ helps avoid naming conflicts, since you may want to put other static html in +public+, but changing this will require web server reconfiguration to let the web server know where to serve the cached files from. -The Page Caching mechanism will automatically add a +.html+ extension to -requests for pages that do not have an extension to make it easy for the -webserver to find those pages and this can be configured by changing the -configuration setting +config.action_controller.page_cache_extension+. +The Page Caching mechanism will automatically add a +.html+ extension to requests for pages that do not have an extension to make it easy for the webserver to find those pages and this can be configured by changing the configuration setting +config.action_controller.page_cache_extension+. -In order to expire this page when a new product is added we could extend our -example controller like this: +In order to expire this page when a new product is added we could extend our example controller like this: class ProductsController < ActionController @@ -89,20 +63,13 @@ class ProductsController < ActionController end -If you want a more complicated expiration scheme, you can use cache sweepers -to expire cached objects when things change. This is covered in the section on Sweepers. +If you want a more complicated expiration scheme, you can use cache sweepers to expire cached objects when things change. This is covered in the section on Sweepers. Note: Page caching ignores all parameters. For example +/products?page=1+ will be written out to the filesystem as +products.html+ with no reference to the +page+ parameter. Thus, if someone requests +/products?page=2+ later, they will get the cached first page. Be careful when page caching GET parameters in the URL! h4. Action Caching -One of the issues with Page Caching is that you cannot use it for pages that -require to restrict access somehow. This is where Action Caching comes in. -Action Caching works like Page Caching except for the fact that the incoming -web request does go from the webserver to the Rails stack and Action Pack so -that before filters can be run on it before the cache is served. This allows -authentication and other restriction to be run while still serving the -result of the output from a cached copy. +One of the issues with Page Caching is that you cannot use it for pages that require to restrict access somehow. This is where Action Caching comes in. Action Caching works like Page Caching except for the fact that the incoming web request does go from the webserver to the Rails stack and Action Pack so that before filters can be run on it before the cache is served. This allows authentication and other restriction to be run while still serving the result of the output from a cached copy. Clearing the cache works in the exact same way as with Page Caching. @@ -125,37 +92,19 @@ class ProductsController < ActionController end -You can also use +:if+ (or +:unless+) to pass a Proc that specifies when the -action should be cached. Also, you can use +:layout => false+ to cache without -layout so that dynamic information in the layout such as logged in user info -or the number of items in the cart can be left uncached. This feature is -available as of Rails 2.2. +You can also use +:if+ (or +:unless+) to pass a Proc that specifies when the action should be cached. Also, you can use +:layout => false+ to cache without layout so that dynamic information in the layout such as logged in user info or the number of items in the cart can be left uncached. This feature is available as of Rails 2.2. -You can modify the default action cache path by passing a +:cache_path+ option. -This will be passed directly to +ActionCachePath.path_for+. This is handy for -actions with multiple possible routes that should be cached differently. If -a block is given, it is called with the current controller instance. +You can modify the default action cache path by passing a +:cache_path+ option. This will be passed directly to +ActionCachePath.path_for+. This is handy for actions with multiple possible routes that should be cached differently. If a block is given, it is called with the current controller instance. -Finally, if you are using memcached, you can also pass +:expires_in+. In fact, -all parameters not used by +caches_action+ are sent to the underlying cache -store. +Finally, if you are using memcached, you can also pass +:expires_in+. In fact, all parameters not used by +caches_action+ are sent to the underlying cache store. h4. Fragment Caching -Life would be perfect if we could get away with caching the entire contents of -a page or action and serving it out to the world. Unfortunately, dynamic web -applications usually build pages with a variety of components not all of which -have the same caching characteristics. In order to address such a dynamically -created page where different parts of the page need to be cached and expired -differently Rails provides a mechanism called Fragment Caching. +Life would be perfect if we could get away with caching the entire contents of a page or action and serving it out to the world. Unfortunately, dynamic web applications usually build pages with a variety of components not all of which have the same caching characteristics. In order to address such a dynamically created page where different parts of the page need to be cached and expired differently Rails provides a mechanism called Fragment Caching. -Fragment Caching allows a fragment of view logic to be wrapped in a cache -block and served out of the cache store when the next request comes in. +Fragment Caching allows a fragment of view logic to be wrapped in a cache block and served out of the cache store when the next request comes in. -As an example, if you wanted to show all the orders placed on your website -in real time and didn't want to cache that part of the page, but did want -to cache the part of the page which lists all products available, you -could use this piece of code: +As an example, if you wanted to show all the orders placed on your website in real time and didn't want to cache that part of the page, but did want to cache the part of the page which lists all products available, you could use this piece of code: <% Order.find_recent.each do |o| %> @@ -170,9 +119,7 @@ could use this piece of code: <% end %> -The cache block in our example will bind to the action that called it and is -written out to the same place as the Action Cache, which means that if you -want to cache multiple fragments per action, you should provide an +action_suffix+ to the cache call: +The cache block in our example will bind to the action that called it and is written out to the same place as the Action Cache, which means that if you want to cache multiple fragments per action, you should provide an +action_suffix+ to the cache call: <% cache(:action => 'recent', :action_suffix => 'all_products') do %> @@ -185,9 +132,7 @@ and you can expire it using the +expire_fragment+ method, like so: expire_fragment(:controller => 'products', :action => 'recent', :action_suffix => 'all_products') -If you don't want the cache block to bind to the action that called it, You can -also use globally keyed fragments by calling the +cache+ method with a key, like -so: +If you don't want the cache block to bind to the action that called it, You can also use globally keyed fragments by calling the +cache+ method with a key, like so: <% cache('all_available_products') do %> @@ -195,8 +140,7 @@ so: <% end %> -This fragment is then available to all actions in the +ProductsController+ using -the key and can be expired the same way: +This fragment is then available to all actions in the +ProductsController+ using the key and can be expired the same way: expire_fragment('all_available_products') @@ -204,15 +148,9 @@ expire_fragment('all_available_products') h4. Sweepers -Cache sweeping is a mechanism which allows you to get around having a ton of -+expire_{page,action,fragment}+ calls in your code. It does this by moving all the work -required to expire cached content into a +ActionController::Caching::Sweeper+ -class. This class is an Observer and looks for changes to an object via callbacks, -and when a change occurs it expires the caches associated with that object in -an around or after filter. +Cache sweeping is a mechanism which allows you to get around having a ton of +expire_{page,action,fragment}+ calls in your code. It does this by moving all the work required to expire cached content into a +ActionController::Caching::Sweeper+ class. This class is an Observer and looks for changes to an object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter. -Continuing with our Product controller example, we could rewrite it with a -sweeper like this: +Continuing with our Product controller example, we could rewrite it with a sweeper like this: class ProductSweeper < ActionController::Caching::Sweeper @@ -244,18 +182,13 @@ class ProductSweeper < ActionController::Caching::Sweeper end -You may notice that the actual product gets passed to the sweeper, so if we -were caching the edit action for each product, we could add a expire method -which specifies the page we want to expire: +You may notice that the actual product gets passed to the sweeper, so if we were caching the edit action for each product, we could add a expire method which specifies the page we want to expire: expire_action(:controller => 'products', :action => 'edit', :id => product) -Then we add it to our controller to tell it to call the sweeper when certain -actions are called. So, if we wanted to expire the cached content for the -list and edit actions when the create action was called, we could do the -following: +Then we add it to our controller to tell it to call the sweeper when certain actions are called. So, if we wanted to expire the cached content for the list and edit actions when the create action was called, we could do the following: class ProductsController < ActionController @@ -273,10 +206,7 @@ end h4. SQL Caching -Query caching is a Rails feature that caches the result set returned by each -query so that if Rails encounters the same query again for that request, it -will use the cached result set as opposed to running the query against the -database again. +Query caching is a Rails feature that caches the result set returned by each query so that if Rails encounters the same query again for that request, it will use the cached result set as opposed to running the query against the database again. For example: @@ -296,34 +226,19 @@ class ProductsController < ActionController end -The second time the same query is run against the database, it's not actually -going to hit the database. The first time the result is returned from the query -it is stored in the query cache (in memory) and the second time it's pulled from memory. +The second time the same query is run against the database, it's not actually going to hit the database. The first time the result is returned from the query it is stored in the query cache (in memory) and the second time it's pulled from memory. -However, it's important to note that query caches are created at the start of an action and destroyed at the end of -that action and thus persist only for the duration of the action. If you'd like to store query results in a more -persistent fashion, you can in Rails by using low level caching. +However, it's important to note that query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action. If you'd like to store query results in a more persistent fashion, you can in Rails by using low level caching. h3. Cache Stores -Rails (as of 2.1) provides different stores for the cached data created by action and -fragment caches. Page caches are always stored on disk. +Rails provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk. -Rails 2.1 and above provide +ActiveSupport::Cache::Store+ which can be used to -cache strings. Some cache store implementations, like +MemoryStore+, are able to -cache arbitrary Ruby objects, but don't count on every cache store to be able -to do that. +Rails 2.1 and above provide +ActiveSupport::Cache::Store+ which can be used to cache strings. Some cache store implementations, like +MemoryStore+, are able to cache arbitrary Ruby objects, but don't count on every cache store to be able to do that. The default cache stores provided with Rails include: -1) +ActiveSupport::Cache::MemoryStore+: A cache store implementation which stores -everything into memory in the same process. If you're running multiple Ruby on -Rails server processes (which is the case if you're using mongrel_cluster or -Phusion Passenger), then this means that your Rails server process instances -won't be able to share cache data with each other. If your application never -performs manual cache item expiry (e.g. when you‘re using generational cache -keys), then using +MemoryStore+ is ok. Otherwise, consider carefully whether you -should be using this cache store. +1) +ActiveSupport::Cache::MemoryStore+: A cache store implementation which stores everything into memory in the same process. If you're running multiple Ruby on Rails server processes (which is the case if you're using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances won't be able to share cache data with each other. If your application never performs manual cache item expiry (e.g. when you‘re using generational cache keys), then using +MemoryStore+ is ok. Otherwise, consider carefully whether you should be using this cache store. +MemoryStore+ is not only able to store strings, but also arbitrary Ruby objects. @@ -333,36 +248,23 @@ should be using this cache store. ActionController::Base.cache_store = :memory_store -2) +ActiveSupport::Cache::FileStore+: Cached data is stored on the disk, this is -the default store and the default path for this store is +tmp/cache+. Works -well for all types of environments and allows all processes running from the -same application directory to access the cached content. If +tmp/cache+ does not -exist, the default store becomes +MemoryStore+. - +2) +ActiveSupport::Cache::FileStore+: Cached data is stored on the disk, this is the default store and the default path for this store is +tmp/cache+. Works well for all types of environments and allows all processes running from the same application directory to access the cached content. If +tmp/cache+ does not exist, the default store becomes +MemoryStore+. ActionController::Base.cache_store = :file_store, "/path/to/cache/directory" -3) +ActiveSupport::Cache::DRbStore+: Cached data is stored in a separate shared -DRb process that all servers communicate with. This works for all environments -and only keeps one cache around for all processes, but requires that you run -and manage a separate DRb process. - +3) +ActiveSupport::Cache::DRbStore+: Cached data is stored in a separate shared DRb process that all servers communicate with. This works for all environments and only keeps one cache around for all processes, but requires that you run and manage a separate DRb process. ActionController::Base.cache_store = :drb_store, "druby://localhost:9192" -4) +ActiveSupport::Cache::MemCacheStore+: Works like +DRbStore+, -but uses Danga's +memcached+ instead. Rails uses the bundled +memcached-client+ gem by -default. This is currently the most popular cache store for production websites. +4) +ActiveSupport::Cache::MemCacheStore+: Works like +DRbStore+, but uses Danga's +memcached+ instead. Rails uses the bundled +memcached-client+ gem by default. This is currently the most popular cache store for production websites. Special features: -* Clustering and load balancing. One can specify multiple memcached servers, and -+MemCacheStore+ will load balance between all available servers. If a server goes -down, then +MemCacheStore+ will ignore it until it goes back online. +* Clustering and load balancing. One can specify multiple memcached servers, and +MemCacheStore+ will load balance between all available servers. If a server goes down, then +MemCacheStore+ will ignore it until it goes back online. * Time-based expiry support. See +write+ and the +:expires_in+ option. * Per-request in memory cache for all communication with the +memcached+ server(s). @@ -372,20 +274,11 @@ It also accepts a hash of additional options: * +:readonly+: a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write. * +:multithread+: a boolean value that adds thread safety to read/write operations - it is unlikely you'll need to use this option as the Rails threadsafe! method offers the same functionality. -The read and write methods of the +MemCacheStore+ accept an options hash too. -When reading you can specify +:raw => true+ to prevent the object being marshaled -(by default this is false which means the raw value in the cache is passed to -+Marshal.load+ before being returned to you.) - -When writing to the cache it is also possible to specify +:raw => true+ means -the value is not passed to +Marshal.dump+ before being stored in the cache (by -default this is false). +The read and write methods of the +MemCacheStore+ accept an options hash too. When reading you can specify +:raw => true+ to prevent the object being marshaled (by default this is false which means the raw value in the cache is passed to +Marshal.load+ before being returned to you.) -The write method also accepts an +:unless_exist+ flag which determines whether -the memcached add (when true) or set (when false) method is used to store the -item in the cache and an +:expires_in+ option that specifies the time-to-live -for the cached item in seconds. +When writing to the cache it is also possible to specify +:raw => true+ means the value is not passed to +Marshal.dump+ before being stored in the cache (by default this is false). +The write method also accepts an +:unless_exist+ flag which determines whether the memcached add (when true) or set (when false) method is used to store the item in the cache and an +:expires_in+ option that specifies the time-to-live for the cached item in seconds. ActionController::Base.cache_store = :mem_cache_store, "localhost" @@ -393,14 +286,11 @@ ActionController::Base.cache_store = :mem_cache_store, "localhost" 5) +ActiveSupport::Cache::SynchronizedMemoryStore+: Like +MemoryStore+ but thread-safe. - ActionController::Base.cache_store = :synchronized_memory_store -6) +ActiveSupport::Cache::CompressedMemCacheStore+: Works just like the regular -+MemCacheStore+ but uses GZip to decompress/compress on read/write. - +6) +ActiveSupport::Cache::CompressedMemCacheStore+: Works just like the regular +MemCacheStore+ but uses GZip to decompress/compress on read/write. ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost" @@ -408,15 +298,13 @@ ActionController::Base.cache_store = :compressed_mem_cache_store, "localhost" 7) Custom store: You can define your own cache store (new in Rails 2.1). - ActionController::Base.cache_store = MyOwnStore.new("parameter") NOTE: +config.cache_store+ can be used in place of +ActionController::Base.cache_store+ in your +Rails::Initializer.run+ block in +environment.rb+ -In addition to all of this, Rails also adds the +ActiveRecord::Base#cache_key+ -method that generates a key using the class name, +id+ and +updated_at+ timestamp (if available). +In addition to all of this, Rails also adds the +ActiveRecord::Base#cache_key+ method that generates a key using the class name, +id+ and +updated_at+ timestamp (if available). You can access these cache stores at a low level for storing queries and other objects. Here's an example: @@ -428,21 +316,11 @@ Rails.cache.read("city") # => "Duckburgh" h3. Conditional GET support -Conditional GETs are a feature of the HTTP specification that provide a way for web -servers to tell browsers that the response to a GET request hasn't changed -since the last request and can be safely pulled from the browser cache. +Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn't changed since the last request and can be safely pulled from the browser cache. -They work by using the +HTTP_IF_NONE_MATCH+ and +HTTP_IF_MODIFIED_SINCE+ headers -to pass back and forth both a unique content identifier and the timestamp of -when the content was last changed. If the browser makes a request where the -content identifier (etag) or last modified since timestamp matches the server’s -version then the server only needs to send back an empty response with a not -modified status. +They work by using the +HTTP_IF_NONE_MATCH+ and +HTTP_IF_MODIFIED_SINCE+ headers to pass back and forth both a unique content identifier and the timestamp of when the content was last changed. If the browser makes a request where the content identifier (etag) or last modified since timestamp matches the server’s version then the server only needs to send back an empty response with a not modified status. -It is the server's (i.e. our) responsibility to look for a last modified -timestamp and the if-none-match header and determine whether or not to send -back the full response. With conditional-get support in rails this is a pretty -easy task: +It is the server's (i.e. our) responsibility to look for a last modified timestamp and the if-none-match header and determine whether or not to send back the full response. With conditional-get support in rails this is a pretty easy task: class ProductsController < ApplicationController @@ -465,9 +343,7 @@ class ProductsController < ApplicationController end -If you don't have any special response processing and are using the default -rendering mechanism (i.e. you're not using respond_to or calling render -yourself) then you’ve got an easy helper in fresh_when: +If you don't have any special response processing and are using the default rendering mechanism (i.e. you're not using respond_to or calling render yourself) then you’ve got an easy helper in fresh_when: class ProductsController < ApplicationController @@ -484,11 +360,7 @@ end h3. Advanced Caching -Along with the built-in mechanisms outlined above, a number of excellent -plugins exist to help with finer grained control over caching. These include -Chris Wanstrath's excellent cache_fu plugin (more info "here": http://errtheblog.com/posts/57-kickin-ass-w-cachefu) and Evan Weaver's -interlock plugin (more info "here": http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/). Both -of these plugins play nice with memcached and are a must-see for anyone +Along with the built-in mechanisms outlined above, a number of excellent plugins exist to help with finer grained control over caching. These include Chris Wanstrath's excellent cache_fu plugin (more info "here": http://errtheblog.com/posts/57-kickin-ass-w-cachefu) and Evan Weaver's interlock plugin (more info "here": http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/). Both of these plugins play nice with memcached and are a must-see for anyone seriously considering optimizing their caching needs. Also the new "Cache money":http://github.com/nkallen/cache-money/tree/master plugin is supposed to be mad cool. -- cgit v1.2.3 From 3014f0f4c53da5b10294670976080b0036c016dd Mon Sep 17 00:00:00 2001 From: Joseph Pecoraro Date: Fri, 29 May 2009 16:26:50 -0400 Subject: Capitalized Rails where appropriate. --- railties/guides/source/caching_with_rails.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 6d8c51355b..c4af3a948f 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -320,7 +320,7 @@ Conditional GETs are a feature of the HTTP specification that provide a way for They work by using the +HTTP_IF_NONE_MATCH+ and +HTTP_IF_MODIFIED_SINCE+ headers to pass back and forth both a unique content identifier and the timestamp of when the content was last changed. If the browser makes a request where the content identifier (etag) or last modified since timestamp matches the server’s version then the server only needs to send back an empty response with a not modified status. -It is the server's (i.e. our) responsibility to look for a last modified timestamp and the if-none-match header and determine whether or not to send back the full response. With conditional-get support in rails this is a pretty easy task: +It is the server's (i.e. our) responsibility to look for a last modified timestamp and the if-none-match header and determine whether or not to send back the full response. With conditional-get support in Rails this is a pretty easy task: class ProductsController < ApplicationController -- cgit v1.2.3 From 7749e1784c1127cf532d9f41a0331ed266ebec6d Mon Sep 17 00:00:00 2001 From: Joseph Pecoraro Date: Fri, 29 May 2009 21:09:01 -0400 Subject: Grammer: 'a' => 'an' where applicable. --- railties/guides/source/caching_with_rails.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index c4af3a948f..2865bc504a 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -182,7 +182,7 @@ class ProductSweeper < ActionController::Caching::Sweeper end -You may notice that the actual product gets passed to the sweeper, so if we were caching the edit action for each product, we could add a expire method which specifies the page we want to expire: +You may notice that the actual product gets passed to the sweeper, so if we were caching the edit action for each product, we could add an expire method which specifies the page we want to expire: expire_action(:controller => 'products', :action => 'edit', :id => product) -- cgit v1.2.3 From acde75c84abe5ae4be3c07bc1afdade78de7a9e8 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 25 Oct 2009 13:14:52 +0100 Subject: Caching guide: documents that page/action caching run in an after_filter, and this spurious cache entries are avoided just by halting the request --- railties/guides/source/caching_with_rails.textile | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 2865bc504a..067250e677 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -67,6 +67,8 @@ If you want a more complicated expiration scheme, you can use cache sweepers to Note: Page caching ignores all parameters. For example +/products?page=1+ will be written out to the filesystem as +products.html+ with no reference to the +page+ parameter. Thus, if someone requests +/products?page=2+ later, they will get the cached first page. Be careful when page caching GET parameters in the URL! +INFO: Page caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Tipically, a redirection in some before filter that checks request preconditions does the job. + h4. Action Caching One of the issues with Page Caching is that you cannot use it for pages that require to restrict access somehow. This is where Action Caching comes in. Action Caching works like Page Caching except for the fact that the incoming web request does go from the webserver to the Rails stack and Action Pack so that before filters can be run on it before the cache is served. This allows authentication and other restriction to be run while still serving the result of the output from a cached copy. @@ -98,6 +100,8 @@ You can modify the default action cache path by passing a +:cache_path+ option. Finally, if you are using memcached, you can also pass +:expires_in+. In fact, all parameters not used by +caches_action+ are sent to the underlying cache store. +INFO: Action caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Tipically, a redirection in some before filter that checks request preconditions does the job. + h4. Fragment Caching Life would be perfect if we could get away with caching the entire contents of a page or action and serving it out to the world. Unfortunately, dynamic web applications usually build pages with a variety of components not all of which have the same caching characteristics. In order to address such a dynamically created page where different parts of the page need to be cached and expired differently Rails provides a mechanism called Fragment Caching. -- cgit v1.2.3 From 243cfceba58ea8ccd6e41be32a140da6cb888b3f Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 25 Oct 2009 13:54:42 +0100 Subject: corrects typo in previous commit --- railties/guides/source/caching_with_rails.textile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index 067250e677..ac6f944457 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -67,7 +67,7 @@ If you want a more complicated expiration scheme, you can use cache sweepers to Note: Page caching ignores all parameters. For example +/products?page=1+ will be written out to the filesystem as +products.html+ with no reference to the +page+ parameter. Thus, if someone requests +/products?page=2+ later, they will get the cached first page. Be careful when page caching GET parameters in the URL! -INFO: Page caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Tipically, a redirection in some before filter that checks request preconditions does the job. +INFO: Page caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Typically, a redirection in some before filter that checks request preconditions does the job. h4. Action Caching @@ -100,7 +100,7 @@ You can modify the default action cache path by passing a +:cache_path+ option. Finally, if you are using memcached, you can also pass +:expires_in+. In fact, all parameters not used by +caches_action+ are sent to the underlying cache store. -INFO: Action caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Tipically, a redirection in some before filter that checks request preconditions does the job. +INFO: Action caching runs in an after filter. Thus, invalid requests won't generate spurious cache entries as long as you halt them. Typically, a redirection in some before filter that checks request preconditions does the job. h4. Fragment Caching -- cgit v1.2.3 From 47683b7d0ec5489aa01d1526c1b147528eca6170 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 24 Feb 2010 01:34:04 +0100 Subject: caching guide: fixes a typo, thanks to Jonathan Bryan --- railties/guides/source/caching_with_rails.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'railties/guides/source/caching_with_rails.textile') diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile index ac6f944457..e27c2a6dc6 100644 --- a/railties/guides/source/caching_with_rails.textile +++ b/railties/guides/source/caching_with_rails.textile @@ -152,7 +152,7 @@ expire_fragment('all_available_products') h4. Sweepers -Cache sweeping is a mechanism which allows you to get around having a ton of +expire_{page,action,fragment}+ calls in your code. It does this by moving all the work required to expire cached content into a +ActionController::Caching::Sweeper+ class. This class is an Observer and looks for changes to an object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter. +Cache sweeping is a mechanism which allows you to get around having a ton of +expire_{page,action,fragment}+ calls in your code. It does this by moving all the work required to expire cached content into an +ActionController::Caching::Sweeper+ subclass. This class is an observer and looks for changes to an object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter. Continuing with our Product controller example, we could rewrite it with a sweeper like this: -- cgit v1.2.3