diff options
Diffstat (limited to 'actionpack/lib/action_controller')
-rw-r--r-- | actionpack/lib/action_controller/caching.rb | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb index 5bedb17cd1..ef60d0a73e 100644 --- a/actionpack/lib/action_controller/caching.rb +++ b/actionpack/lib/action_controller/caching.rb @@ -17,7 +17,7 @@ module ActionController #:nodoc: end end - # Page caching is an approach to caching where the entire action output of is stored as a HTML file that the web server + # Page caching is an approach to caching where the entire action output of is stored as a HTML file that the web server # can serve without going through the Action Pack. This can be as much as 100 times faster than going through the process of dynamically # generating the content. Unfortunately, this incredible speed-up is only available to stateless pages where all visitors # are treated the same. Content management systems -- including weblogs and wikis -- have many pages that are a great fit @@ -78,7 +78,7 @@ module ActionController #:nodoc: File.delete(page_cache_path(path)) if File.exists?(page_cache_path(path)) end end - + # Manually cache the +content+ in the key determined by +path+. Example: # cache_page "I'm the cached content", "/lists/show" def cache_page(content, path) @@ -94,18 +94,18 @@ module ActionController #:nodoc: # matches the triggering url. def caches_page(*actions) return unless perform_caching - actions.each do |action| + actions.each do |action| class_eval "after_filter { |c| c.cache_page if c.action_name == '#{action}' }" end end - + private def page_cache_file(path) name = ((path.empty? || path == "/") ? "/index" : URI.unescape(path)) name << page_cache_extension unless (name.split('/').last || name).include? '.' return name end - + def page_cache_path(path) page_cache_directory + page_cache_file(path) end @@ -138,7 +138,7 @@ module ActionController #:nodoc: end end - # Action caching is similar to page caching by the fact that the entire output of the response is cached, but unlike page caching, + # Action caching is similar to page caching by the fact that the entire output of the response is cached, but unlike page caching, # every request still goes through the Action Pack. The key benefit of this is that filters are run before the cache is served, which # allows for authentication and other restrictions on whether someone is allowed to see the cache. Example: # @@ -184,7 +184,7 @@ module ActionController #:nodoc: def initialize(*actions) @actions = actions end - + def before(controller) return unless @actions.include?(controller.action_name.intern) if cache = controller.read_fragment(controller.url_for.split("://").last) @@ -193,7 +193,7 @@ module ActionController #:nodoc: false end end - + def after(controller) return if !@actions.include?(controller.action_name.intern) || controller.rendered_action_cache controller.write_fragment(controller.url_for.split("://").last, controller.response.body) @@ -211,7 +211,7 @@ module ActionController #:nodoc: # <%= render_collection_of_partials "topic", Topic.find_all %> # <% end %> # - # This cache will bind to the name of action that called it. So you would be able to invalidate it using + # This cache will bind to the name of action that called it. So you would be able to invalidate it using # <tt>expire_fragment(:controller => "topics", :action => "list")</tt> -- if that was the controller/action used. This is not too helpful # if you need to cache multiple fragments per action or if the action itself is cached using <tt>caches_action</tt>. So instead we should # qualify the name of the action used with something like: @@ -272,7 +272,7 @@ module ActionController #:nodoc: # Called by CacheHelper#cache def cache_erb_fragment(block, name = {}, options = nil) unless perform_caching then block.call; return end - + buffer = eval("_erbout", block.binding) if cache = read_fragment(name, options) @@ -283,7 +283,7 @@ module ActionController #:nodoc: write_fragment(name, buffer[pos..-1], options) end end - + def write_fragment(name, content, options = nil) return unless perform_caching @@ -293,7 +293,7 @@ module ActionController #:nodoc: end content end - + def read_fragment(name, options = nil) return unless perform_caching @@ -302,7 +302,7 @@ module ActionController #:nodoc: fragment_cache_store.read(key, options) end end - + # Name can take one of three forms: # * String: This would normally take the form of a path like "pages/45/notes" # * Hash: Is treated as an implicit call to url_for, like { :controller => "pages", :action => "notes", :id => 45 } @@ -355,15 +355,15 @@ module ActionController #:nodoc: def read(name, options=nil) #:nodoc: @mutex.synchronize { super } end - + def write(name, value, options=nil) #:nodoc: @mutex.synchronize { super } end - + def delete(name, options=nil) #:nodoc: @mutex.synchronize { super } end - + def delete_matched(matcher, options=nil) #:nodoc: @mutex.synchronize { super } end @@ -386,26 +386,28 @@ module ActionController #:nodoc: super() @address = address @data = DRbObject.new(nil, address) - end + end end class MemCacheStore < MemoryStore #:nodoc: - attr_reader :address + attr_reader :addresses - def initialize(address = 'localhost') + def initialize(*addresses) super() - @address = address - @data = MemCache.new(address) - end + addresses = addresses.flatten + addresses = ["localhost"] if addresses.empty? + @addresses = addresses + @data = MemCache.new(*addresses) + end end class UnthreadedFileStore #:nodoc: attr_reader :cache_path - + def initialize(cache_path) @cache_path = cache_path end - + def write(name, value, options = nil) #:nodoc: ensure_cache_path(File.dirname(real_file_path(name))) File.open(real_file_path(name), "wb+") { |f| f.write(value) } @@ -426,7 +428,7 @@ module ActionController #:nodoc: def delete_matched(matcher, options) #:nodoc: search_dir(@cache_path) do |f| if f =~ matcher - begin + begin File.delete(f) rescue Object => e # If there's no cache, then there's nothing to complain about @@ -434,12 +436,12 @@ module ActionController #:nodoc: end end end - + private def real_file_path(name) '%s/%s.cache' % [@cache_path, name.gsub('?', '.').gsub(':', '.')] end - + def ensure_cache_path(path) FileUtils.makedirs(path) unless File.exists?(path) end @@ -470,10 +472,10 @@ module ActionController #:nodoc: # Sweepers are the terminators of the caching world and responsible for expiring caches when model objects change. # They do this by being half-observers, half-filters and implementing callbacks for both roles. A Sweeper example: - # + # # class ListSweeper < ActionController::Caching::Sweeper # observe List, Item - # + # # def after_save(record) # list = record.is_a?(List) ? record : record.list # expire_page(:controller => "lists", :action => %w( show public feed ), :id => list.id) @@ -514,11 +516,11 @@ module ActionController #:nodoc: end end end - + if defined?(ActiveRecord::Observer) class Sweeper < ActiveRecord::Observer #:nodoc: attr_accessor :controller - + def before(controller) self.controller = controller callback(:before) @@ -527,16 +529,16 @@ module ActionController #:nodoc: def after(controller) callback(:after) end - + private def callback(timing) controller_callback_method_name = "#{timing}_#{controller.controller_name.underscore}" action_callback_method_name = "#{controller_callback_method_name}_#{controller.action_name}" - + send(controller_callback_method_name) if respond_to?(controller_callback_method_name) send(action_callback_method_name) if respond_to?(action_callback_method_name) end - + def method_missing(method, *arguments) return if @controller.nil? @controller.send(method, *arguments) |