Ticket #8231: action_caching_speedup_trunk.patch
| File action_caching_speedup_trunk.patch, 6.0 kB (added by skaes, 2 years ago) |
|---|
-
test/controller/caching_test.rb
old new 224 224 def test_xml_version_of_resource_is_treated_as_different_cache 225 225 @mock_controller.mock_url_for = 'http://example.org/posts/' 226 226 @mock_controller.mock_path = '/posts/index.xml' 227 path_object = @path_class.new(@mock_controller )227 path_object = @path_class.new(@mock_controller, {}) 228 228 assert_equal 'xml', path_object.extension 229 229 assert_equal 'example.org/posts/index.xml', path_object.path 230 230 end … … 233 233 @mock_controller.mock_url_for = 'http://example.org/' 234 234 @mock_controller.mock_path = '/' 235 235 236 assert_equal 'example.org/index', @path_class.path_for(@mock_controller )236 assert_equal 'example.org/index', @path_class.path_for(@mock_controller, {}) 237 237 end 238 238 239 239 def test_file_extensions -
lib/action_controller/caching.rb
old new 1 1 require 'fileutils' 2 2 require 'uri' 3 require 'set' 3 4 4 5 module ActionController #:nodoc: 5 6 # Caching is a cheap way of speeding up slow applications by keeping the result of calculations, renderings, and database calls … … 177 178 module Actions 178 179 def self.included(base) #:nodoc: 179 180 base.extend(ClassMethods) 180 base.send(:attr_accessor, :rendered_action_cache) 181 base.class_eval do 182 attr_accessor :rendered_action_cache, :action_cache_path 183 alias_method_chain :protected_instance_variables, :action_caching 184 end 185 end 186 187 def protected_instance_variables_with_action_caching 188 protected_instance_variables_without_action_caching + %w(@action_cache_path) 181 189 end 182 190 183 191 module ClassMethods #:nodoc: 184 192 def caches_action(*actions) 185 193 return unless perform_caching 186 around_filter(ActionCacheFilter.new(*actions)) 194 action_cache_filter = ActionCacheFilter.new(*actions) 195 before_filter action_cache_filter 196 after_filter action_cache_filter 187 197 end 188 198 end 189 199 … … 200 210 201 211 class ActionCacheFilter #:nodoc: 202 212 def initialize(*actions, &block) 203 @ actions = actions204 @ options = @actions.last.is_a?(Hash) ? @actions.pop : {}213 @options = actions.last.is_a?(Hash) ? actions.pop : {} 214 @actions = Set.new actions 205 215 end 206 216 207 217 def before(controller) 208 218 return unless @actions.include?(controller.action_name.intern) 209 action_cache_path = ActionCachePath.new(controller, path_options_for(controller))210 if cache = controller.read_fragment( action_cache_path.path)219 cache_path = ActionCachePath.new(controller, path_options_for(controller, @options)) 220 if cache = controller.read_fragment(cache_path.path) 211 221 controller.rendered_action_cache = true 212 set_content_type!( action_cache_path)222 set_content_type!(controller, cache_path) 213 223 controller.send(:render_text, cache) 214 224 false 225 else 226 controller.action_cache_path = cache_path 215 227 end 216 228 end 217 229 218 230 def after(controller) 219 231 return if !@actions.include?(controller.action_name.intern) || controller.rendered_action_cache 220 controller.write_fragment( ActionCachePath.path_for(controller, path_options_for(controller)), controller.response.body)232 controller.write_fragment(controller.action_cache_path.path, controller.response.body) 221 233 end 222 234 223 235 private 224 236 225 def set_content_type!(action_cache_path) 226 if extention = action_cache_path.extension 227 content_type = Mime::EXTENSION_LOOKUP[extention] 228 action_cache_path.controller.response.content_type = content_type.to_s 229 end 237 def set_content_type!(controller, extension) 238 controller.response.content_type = Mime::EXTENSION_LOOKUP[extension].to_s if extension 230 239 end 231 240 232 def path_options_for(controller )233 ( @options[:cache_path].respond_to?(:call) ? @options[:cache_path].call(controller) : @options[:cache_path]) || {}241 def path_options_for(controller, options) 242 ((path_options = options[:cache_path]).respond_to?(:call) ? path_options.call(controller) : path_options) || {} 234 243 end 235 244 236 245 end 237 246 238 247 class ActionCachePath 239 attr_reader : controller, :options248 attr_reader :path, :extension 240 249 241 250 class << self 242 def path_for( *args, &block)243 new( *args).path251 def path_for(controller, options) 252 new(controller, options).path 244 253 end 245 254 end 246 255 247 256 def initialize(controller, options = {}) 248 @controller = controller 249 @options = options 250 end 251 252 def path 253 return @path if @path 254 @path = controller.url_for(options).split('://').last 255 normalize! 256 add_extension! 257 URI.unescape(@path) 258 end 259 260 def extension 261 @extension ||= extract_extension(controller.request.path) 257 @extension = extract_extension(controller.request.path) 258 path = controller.url_for(options).split('://').last 259 normalize!(path) 260 add_extension!(path, @extension) 261 @path = URI.unescape(path) 262 262 end 263 263 264 264 private 265 def normalize! 266 @path << 'index' if @path.last == '/'265 def normalize!(path) 266 path << 'index' if path[-1] == ?/ 267 267 end 268 268 269 def add_extension! 270 @path << ".#{extension}" if extension269 def add_extension!(path, extension) 270 path << ".#{extension}" if extension 271 271 end 272 272 273 273 def extract_extension(file_path)