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
|
||||
@@digest_mutex = Mutex.new
|
||||
|
||||
module PerExecutionDigestCacheExpiry
|
||||
def self.before(target)
|
||||
ActionView::LookupContext::DetailsKey.clear
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
# Supported options:
|
||||
#
|
||||
|
|
|
@ -40,7 +40,7 @@ module ActionView
|
|||
initializer "action_view.per_request_digest_cache" do |app|
|
||||
ActiveSupport.on_load(:action_view) do
|
||||
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
|
||||
|
|
|
@ -34,16 +34,14 @@ module ActiveRecord
|
|||
def self.complete(enabled)
|
||||
ActiveRecord::Base.connection.clear_query_cache
|
||||
ActiveRecord::Base.connection.disable_query_cache! unless enabled
|
||||
|
||||
unless ActiveRecord::Base.connected? && ActiveRecord::Base.connection.transaction_open?
|
||||
ActiveRecord::Base.clear_active_connections!
|
||||
end
|
||||
end
|
||||
|
||||
def self.install_executor_hooks(executor = ActiveSupport::Executor)
|
||||
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
|
||||
|
|
|
@ -19,6 +19,23 @@ module ActiveSupport
|
|||
set_callback(:complete, *args, &block)
|
||||
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
|
||||
# +complete+ steps.
|
||||
#
|
||||
|
@ -29,19 +46,11 @@ module ActiveSupport
|
|||
# invoked in that situation.)
|
||||
def self.register_hook(hook, outer: false)
|
||||
if outer
|
||||
run_args = [prepend: true]
|
||||
complete_args = [:after]
|
||||
to_run RunHook.new(hook), prepend: true
|
||||
to_complete :after, CompleteHook.new(hook)
|
||||
else
|
||||
run_args = complete_args = []
|
||||
end
|
||||
|
||||
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
|
||||
to_run RunHook.new(hook)
|
||||
to_complete CompleteHook.new(hook)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -158,6 +158,61 @@ class ExecutorTest < ActiveSupport::TestCase
|
|||
assert_equal :some_state, supplied_state
|
||||
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
|
||||
other_executor = Class.new(ActiveSupport::Executor)
|
||||
|
||||
|
|
Loading…
Reference in New Issue