Avoid bumping the class serial when invoking executor
This commit is contained in:
parent
7b63f56ce0
commit
e8b36e7711
|
@ -6,6 +6,12 @@ module ActionView
|
||||||
class Digestor
|
class Digestor
|
||||||
@@digest_mutex = Mutex.new
|
@@digest_mutex = Mutex.new
|
||||||
|
|
||||||
|
module PerExecutionDigestCacheExpiry
|
||||||
|
def self.before(target)
|
||||||
|
ActionView::LookupContext::DetailsKey.clear
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
# Supported options:
|
# Supported options:
|
||||||
#
|
#
|
||||||
|
|
|
@ -40,7 +40,7 @@ module ActionView
|
||||||
initializer "action_view.per_request_digest_cache" do |app|
|
initializer "action_view.per_request_digest_cache" do |app|
|
||||||
ActiveSupport.on_load(:action_view) do
|
ActiveSupport.on_load(:action_view) do
|
||||||
if app.config.consider_all_requests_local
|
if app.config.consider_all_requests_local
|
||||||
app.executor.to_run { ActionView::LookupContext::DetailsKey.clear }
|
app.executor.to_run ActionView::Digestor::PerExecutionDigestCacheExpiry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,16 +34,14 @@ module ActiveRecord
|
||||||
def self.complete(enabled)
|
def self.complete(enabled)
|
||||||
ActiveRecord::Base.connection.clear_query_cache
|
ActiveRecord::Base.connection.clear_query_cache
|
||||||
ActiveRecord::Base.connection.disable_query_cache! unless enabled
|
ActiveRecord::Base.connection.disable_query_cache! unless enabled
|
||||||
|
|
||||||
|
unless ActiveRecord::Base.connected? && ActiveRecord::Base.connection.transaction_open?
|
||||||
|
ActiveRecord::Base.clear_active_connections!
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.install_executor_hooks(executor = ActiveSupport::Executor)
|
def self.install_executor_hooks(executor = ActiveSupport::Executor)
|
||||||
executor.register_hook(self)
|
executor.register_hook(self)
|
||||||
|
|
||||||
executor.to_complete do
|
|
||||||
unless ActiveRecord::Base.connected? && ActiveRecord::Base.connection.transaction_open?
|
|
||||||
ActiveRecord::Base.clear_active_connections!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,6 +19,23 @@ module ActiveSupport
|
||||||
set_callback(:complete, *args, &block)
|
set_callback(:complete, *args, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class RunHook < Struct.new(:hook) # :nodoc:
|
||||||
|
def before(target)
|
||||||
|
hook_state = target.send(:hook_state)
|
||||||
|
hook_state[hook] = hook.run
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class CompleteHook < Struct.new(:hook) # :nodoc:
|
||||||
|
def before(target)
|
||||||
|
hook_state = target.send(:hook_state)
|
||||||
|
if hook_state.key?(hook)
|
||||||
|
hook.complete hook_state[hook]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
alias after before
|
||||||
|
end
|
||||||
|
|
||||||
# Register an object to be invoked during both the +run+ and
|
# Register an object to be invoked during both the +run+ and
|
||||||
# +complete+ steps.
|
# +complete+ steps.
|
||||||
#
|
#
|
||||||
|
@ -29,19 +46,11 @@ module ActiveSupport
|
||||||
# invoked in that situation.)
|
# invoked in that situation.)
|
||||||
def self.register_hook(hook, outer: false)
|
def self.register_hook(hook, outer: false)
|
||||||
if outer
|
if outer
|
||||||
run_args = [prepend: true]
|
to_run RunHook.new(hook), prepend: true
|
||||||
complete_args = [:after]
|
to_complete :after, CompleteHook.new(hook)
|
||||||
else
|
else
|
||||||
run_args = complete_args = []
|
to_run RunHook.new(hook)
|
||||||
end
|
to_complete CompleteHook.new(hook)
|
||||||
|
|
||||||
to_run(*run_args) do
|
|
||||||
hook_state[hook] = hook.run
|
|
||||||
end
|
|
||||||
to_complete(*complete_args) do
|
|
||||||
if hook_state.key?(hook)
|
|
||||||
hook.complete hook_state[hook]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,61 @@ class ExecutorTest < ActiveSupport::TestCase
|
||||||
assert_equal :some_state, supplied_state
|
assert_equal :some_state, supplied_state
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_hook_insertion_order
|
||||||
|
invoked = []
|
||||||
|
supplied_state = []
|
||||||
|
|
||||||
|
hook_class = Class.new do
|
||||||
|
attr_accessor :letter
|
||||||
|
|
||||||
|
define_method(:initialize) do |letter|
|
||||||
|
self.letter = letter
|
||||||
|
end
|
||||||
|
|
||||||
|
define_method(:run) do
|
||||||
|
invoked << :"run_#{letter}"
|
||||||
|
:"state_#{letter}"
|
||||||
|
end
|
||||||
|
|
||||||
|
define_method(:complete) do |state|
|
||||||
|
invoked << :"complete_#{letter}"
|
||||||
|
supplied_state << state
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
executor.register_hook(hook_class.new(:a))
|
||||||
|
executor.register_hook(hook_class.new(:b))
|
||||||
|
executor.register_hook(hook_class.new(:c), outer: true)
|
||||||
|
executor.register_hook(hook_class.new(:d))
|
||||||
|
|
||||||
|
executor.wrap {}
|
||||||
|
|
||||||
|
assert_equal [:run_c, :run_a, :run_b, :run_d, :complete_a, :complete_b, :complete_d, :complete_c], invoked
|
||||||
|
assert_equal [:state_a, :state_b, :state_d, :state_c], supplied_state
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_class_serial_is_unaffected
|
||||||
|
hook = Class.new do
|
||||||
|
define_method(:run) do
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
define_method(:complete) do |state|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end.new
|
||||||
|
|
||||||
|
executor.register_hook(hook)
|
||||||
|
|
||||||
|
before = RubyVM.stat(:class_serial)
|
||||||
|
executor.wrap {}
|
||||||
|
executor.wrap {}
|
||||||
|
executor.wrap {}
|
||||||
|
after = RubyVM.stat(:class_serial)
|
||||||
|
|
||||||
|
assert_equal before, after
|
||||||
|
end
|
||||||
|
|
||||||
def test_separate_classes_can_wrap
|
def test_separate_classes_can_wrap
|
||||||
other_executor = Class.new(ActiveSupport::Executor)
|
other_executor = Class.new(ActiveSupport::Executor)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue