Skip to content

Commit

Permalink
Merge pull request rails#20384 from kaspth/per-request-cache
Browse files Browse the repository at this point in the history
Use digest cache in development.
  • Loading branch information
dhh committed Jul 20, 2015
2 parents 6ffec3c + 7bd70ba commit 068865a
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 17 deletions.
12 changes: 8 additions & 4 deletions actionview/lib/action_view/digestor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ class Digestor
@@cache = ThreadSafe::Cache.new
@@digest_monitor = Monitor.new

class PerRequestDigestCacheExpiry < Struct.new(:app) # :nodoc:
def call(env)
ActionView::Digestor.cache.clear
app.call(env)
end
end

class << self
# Supported options:
#
Expand Down Expand Up @@ -41,10 +48,7 @@ def compute_and_store_digest(cache_key, options) # called under @@digest_monitor
Digestor
end

digest = klass.new(options).digest
# Store the actual digest if config.cache_template_loading is true
@@cache[cache_key] = stored_digest = digest if ActionView::Resolver.caching?
digest
@@cache[cache_key] = stored_digest = klass.new(options).digest
ensure
# something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache
@@cache.delete_pair(cache_key, false) if pre_stored && !stored_digest
Expand Down
8 changes: 8 additions & 0 deletions actionview/lib/action_view/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ class Railtie < Rails::Railtie # :nodoc:
end
end

initializer "action_view.per_request_digest_cache" do |app|
ActiveSupport.on_load(:action_view) do
if app.config.consider_all_requests_local
app.middleware.use ActionView::Digestor::PerRequestDigestCacheExpiry
end
end
end

initializer "action_view.setup_action_pack" do |app|
ActiveSupport.on_load(:action_controller) do
ActionView::RoutingUrlFor.include(ActionDispatch::Routing::UrlFor)
Expand Down
16 changes: 3 additions & 13 deletions actionview/test/template/digestor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def test_old_style_hash_in_render_invocation
end

def test_variants
assert_digest_difference("messages/new", false, variants: [:iphone]) do
assert_digest_difference("messages/new", variants: [:iphone]) do
change_template("messages/new", :iphone)
change_template("messages/_header", :iphone)
end
Expand All @@ -239,16 +239,6 @@ def test_dependencies_via_options_results_in_different_digest
assert_not_equal digest_phone, digest_fridge_phone
end

def test_cache_template_loading
resolver_before = ActionView::Resolver.caching
ActionView::Resolver.caching = false
assert_digest_difference("messages/edit", true) do
change_template("comments/_comment")
end
ensure
ActionView::Resolver.caching = resolver_before
end

def test_digest_cache_cleanup_with_recursion
first_digest = digest("level/_recursion")
second_digest = digest("level/_recursion")
Expand Down Expand Up @@ -291,9 +281,9 @@ def assert_logged(message)
end
end

def assert_digest_difference(template_name, persistent = false, options = {})
def assert_digest_difference(template_name, options = {})
previous_digest = digest(template_name, options)
ActionView::Digestor.cache.clear unless persistent
ActionView::Digestor.cache.clear

yield

Expand Down
63 changes: 63 additions & 0 deletions railties/test/application/per_request_digest_cache_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
require 'isolation/abstract_unit'
require 'rack/test'
require 'minitest/mock'

require 'action_view'
require 'active_support/testing/method_call_assertions'

class PerRequestDigestCacheTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
include ActiveSupport::Testing::MethodCallAssertions
include Rack::Test::Methods

setup do
build_app
add_to_config 'config.consider_all_requests_local = true'

app_file 'app/models/customer.rb', <<-RUBY
class Customer < Struct.new(:name, :id)
extend ActiveModel::Naming
include ActiveModel::Conversion
end
RUBY

app_file 'config/routes.rb', <<-RUBY
Rails.application.routes.draw do
resources :customers, only: :index
end
RUBY

app_file 'app/controllers/customers_controller.rb', <<-RUBY
class CustomersController < ApplicationController
def index
render [ Customer.new('david', 1), Customer.new('dingus', 2) ]
end
end
RUBY

app_file 'app/views/customers/_customer.html.erb', <<-RUBY
<% cache customer do %>
<%= customer.name %>
<% end %>
RUBY

require "#{app_path}/config/environment"
end

teardown :teardown_app

test "digests are reused when rendering the same template twice" do
get '/customers'
assert_equal 200, last_response.status

assert_equal [ '8ba099b7749542fe765ff34a6824d548' ], ActionView::Digestor.cache.values
assert_equal %w(david dingus), last_response.body.split.map(&:strip)
end

test "template digests are cleared before a request" do
assert_called(ActionView::Digestor.cache, :clear) do
get '/customers'
assert_equal 200, last_response.status
end
end
end

0 comments on commit 068865a

Please sign in to comment.