Ticket #8231: action_caching_speedup.patch
| File action_caching_speedup.patch, 5.9 kB (added by skaes, 2 years ago) |
|---|
-
actionpack/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 … … 163 164 module Actions 164 165 def self.included(base) #:nodoc: 165 166 base.extend(ClassMethods) 166 base.send(:attr_accessor, :rendered_action_cache) 167 base.class_eval do 168 attr_accessor :rendered_action_cache, :action_cache_path 169 alias_method_chain :protected_instance_variables, :action_caching 170 end 171 end 172 173 def protected_instance_variables_with_action_caching 174 protected_instance_variables_without_action_caching + %w(@action_cache_path) 167 175 end 168 176 169 177 module ClassMethods #:nodoc: 170 178 def caches_action(*actions) 171 179 return unless perform_caching 172 around_filter(ActionCacheFilter.new(*actions)) 180 action_cache_filter = ActionCacheFilter.new(*actions) 181 before_filter action_cache_filter 182 after_filter action_cache_filter 173 183 end 174 184 end 175 185 … … 185 195 end 186 196 187 197 class ActionCacheFilter #:nodoc: 188 def initialize(*actions , &block)189 @actions = actions198 def initialize(*actions) 199 @actions = Set.new actions 190 200 end 191 201 192 202 def before(controller) 193 return unless @actions.include?(controller.action_name. intern)194 action_cache_path = ActionCachePath.new(controller)195 if cache = controller.read_fragment( action_cache_path.path)203 return unless @actions.include?(controller.action_name.to_sym) 204 cache_path = ActionCachePath.new(controller, {}) 205 if cache = controller.read_fragment(cache_path.path) 196 206 controller.rendered_action_cache = true 197 set_content_type!( action_cache_path)207 set_content_type!(controller, cache_path.extension) 198 208 controller.send(:render_text, cache) 199 209 false 210 else 211 controller.action_cache_path = cache_path 200 212 end 201 213 end 202 214 203 215 def after(controller) 204 return if !@actions.include?(controller.action_name. intern) || controller.rendered_action_cache205 controller.write_fragment( ActionCachePath.path_for(controller), controller.response.body)216 return if !@actions.include?(controller.action_name.to_sym) || controller.rendered_action_cache 217 controller.write_fragment(controller.action_cache_path.path, controller.response.body) 206 218 end 207 219 208 220 private 209 210 def set_content_type!(action_cache_path) 211 if extention = action_cache_path.extension 212 content_type = Mime::EXTENSION_LOOKUP[extention] 213 action_cache_path.controller.response.content_type = content_type.to_s 214 end 221 def set_content_type!(controller, extension) 222 controller.response.content_type = Mime::EXTENSION_LOOKUP[extension].to_s if extension 215 223 end 216 224 217 225 end 218 226 219 227 class ActionCachePath 220 attr_reader : controller, :options228 attr_reader :path, :extension 221 229 222 230 class << self 223 def path_for( *args, &block)224 new( *args).path231 def path_for(controller, options) 232 new(controller, options).path 225 233 end 226 234 end 227 235 228 236 def initialize(controller, options = {}) 229 @controller = controller 230 @options = options 231 end 232 233 def path 234 return @path if @path 235 @path = controller.url_for(options).split('://').last 236 normalize! 237 add_extension! 238 URI.unescape(@path) 239 end 240 241 def extension 242 @extension ||= extract_extension(controller.request.path) 237 @extension = extract_extension(controller.request.path) 238 path = controller.url_for(options).split('://').last 239 normalize!(path) 240 add_extension!(path, @extension) 241 @path = URI.unescape(path) 243 242 end 244 243 245 244 private 246 def normalize! 247 @path << 'index' if @path.last == '/'245 def normalize!(path) 246 path << 'index' if path[-1] == ?/ 248 247 end 249 248 250 def add_extension! 251 @path << ".#{extension}" if extension249 def add_extension!(path, extension) 250 path << ".#{extension}" if extension 252 251 end 253 252 254 253 def extract_extension(file_path) -
actionpack/test/controller/caching_test.rb
old new 97 97 caches_action :index 98 98 99 99 def index 100 sleep 0.01 100 101 @cache_this = Time.now.to_f.to_s 101 102 render :text => @cache_this 102 103 end … … 195 196 def test_xml_version_of_resource_is_treated_as_different_cache 196 197 @mock_controller.mock_url_for = 'http://example.org/posts/' 197 198 @mock_controller.mock_path = '/posts/index.xml' 198 path_object = @path_class.new(@mock_controller )199 path_object = @path_class.new(@mock_controller, {}) 199 200 assert_equal 'xml', path_object.extension 200 201 assert_equal 'example.org/posts/index.xml', path_object.path 201 202 end … … 204 205 @mock_controller.mock_url_for = 'http://example.org/' 205 206 @mock_controller.mock_path = '/' 206 207 207 assert_equal 'example.org/index', @path_class.path_for(@mock_controller )208 assert_equal 'example.org/index', @path_class.path_for(@mock_controller, {}) 208 209 end 209 210 210 211 def test_file_extensions