Merge pull request #39428 from etiennebarrie/thread-local-current-attributes

Allow using thread variables for CurrentAttributes instances
This commit is contained in:
Jean Boussier 2021-07-22 16:40:10 +02:00 committed by GitHub
commit fcacb93295
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 1 deletions

View File

@ -117,6 +117,10 @@ module ActiveSupport
def self.utc_to_local_returns_utc_offset_times=(value) def self.utc_to_local_returns_utc_offset_times=(value)
DateAndTime::Compatibility.utc_to_local_returns_utc_offset_times = value DateAndTime::Compatibility.utc_to_local_returns_utc_offset_times = value
end end
def self.current_attributes_use_thread_variables=(value)
CurrentAttributes._use_thread_variables = value
end
end end
autoload :I18n, "active_support/i18n" autoload :I18n, "active_support/i18n"

View File

@ -143,13 +143,23 @@ module ActiveSupport
current_instances.clear current_instances.clear
end end
def _use_thread_variables=(value) # :nodoc:
@@use_thread_variables = value
end
@@use_thread_variables = false
private private
def generated_attribute_methods def generated_attribute_methods
@generated_attribute_methods ||= Module.new.tap { |mod| include mod } @generated_attribute_methods ||= Module.new.tap { |mod| include mod }
end end
def current_instances def current_instances
Thread.current[:current_attributes_instances] ||= {} if @@use_thread_variables
Thread.current.thread_variable_get(:current_attributes_instances) ||
Thread.current.thread_variable_set(:current_attributes_instances, {})
else
Thread.current[:current_attributes_instances] ||= {}
end
end end
def current_instances_key def current_instances_key

View File

@ -174,4 +174,23 @@ class CurrentAttributesTest < ActiveSupport::TestCase
test "respond_to? for methods that have not been called" do test "respond_to? for methods that have not been called" do
assert_equal true, Current.respond_to?("respond_to_test") assert_equal true, Current.respond_to?("respond_to_test")
end end
test "CurrentAttributes use fiber-local variables" do
Session.current = 42
enumerator = Enumerator.new do |yielder|
yielder.yield Session.current
end
assert_nil enumerator.next
end
test "CurrentAttributes can use thread-local variables" do
ActiveSupport::CurrentAttributes._use_thread_variables = true
Session.current = 42
enumerator = Enumerator.new do |yielder|
yielder.yield Session.current
end
assert_equal 42, enumerator.next
ensure
ActiveSupport::CurrentAttributes._use_thread_variables = false
end
end end