diff options
-rw-r--r-- | activerecord/lib/active_record/scoping.rb | 6 | ||||
-rw-r--r-- | activerecord/test/cases/base_test.rb | 4 | ||||
-rw-r--r-- | activesupport/lib/active_support/notifications.rb | 4 | ||||
-rw-r--r-- | activesupport/lib/active_support/per_thread_registry.rb | 48 |
4 files changed, 32 insertions, 30 deletions
diff --git a/activerecord/lib/active_record/scoping.rb b/activerecord/lib/active_record/scoping.rb index 6ab36a23a7..0cf3d59985 100644 --- a/activerecord/lib/active_record/scoping.rb +++ b/activerecord/lib/active_record/scoping.rb @@ -36,7 +36,7 @@ module ActiveRecord # to get the current_scope for the +Board+ model, then you would use the # following code: # - # registry = ActiveRecord::Scoping::ScopeRegistry.instance + # registry = ActiveRecord::Scoping::ScopeRegistry # registry.set_value_for(:current_scope, "Board", some_new_scope) # # Now when you run: @@ -52,10 +52,6 @@ module ActiveRecord class ScopeRegistry # :nodoc: extend ActiveSupport::PerThreadRegistry - class << self - delegate :value_for, :set_value_for, to: :instance - end - VALID_SCOPE_TYPES = [:current_scope, :ignore_default_scope] def initialize diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 83fc0b48f9..bd568af06a 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1377,9 +1377,9 @@ class BasicsTest < ActiveRecord::TestCase UnloadablePost.send(:current_scope=, UnloadablePost.all) UnloadablePost.unloadable - assert_not_nil ActiveRecord::Scoping::ScopeRegistry.instance.value_for(:current_scope, "UnloadablePost") + assert_not_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, "UnloadablePost") ActiveSupport::Dependencies.remove_unloadable_constants! - assert_nil ActiveRecord::Scoping::ScopeRegistry.instance.value_for(:current_scope, "UnloadablePost") + assert_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, "UnloadablePost") ensure Object.class_eval{ remove_const :UnloadablePost } if defined?(UnloadablePost) end diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb index 5c985601f4..c45358bba9 100644 --- a/activesupport/lib/active_support/notifications.rb +++ b/activesupport/lib/active_support/notifications.rb @@ -193,10 +193,6 @@ module ActiveSupport class InstrumentationRegistry # :nodoc: extend ActiveSupport::PerThreadRegistry - class << self - delegate :instrumenter_for, to: :instance - end - def initialize @registry = {} end diff --git a/activesupport/lib/active_support/per_thread_registry.rb b/activesupport/lib/active_support/per_thread_registry.rb index 926df8b4cf..79ff61ca90 100644 --- a/activesupport/lib/active_support/per_thread_registry.rb +++ b/activesupport/lib/active_support/per_thread_registry.rb @@ -1,7 +1,11 @@ module ActiveSupport # This module is used to encapsulate access to thread local variables. # - # Given + # Instead of polluting the thread locals namespace: + # + # Thread.current[:connection_handler] + # + # you define a class that extends this module: # # module ActiveRecord # class RuntimeRegistry @@ -11,34 +15,40 @@ module ActiveSupport # end # end # - # <tt>ActiveRecord::RuntimeRegistry</tt> gets an +instance+ class method - # that returns an instance of the class unique to the current thread. Thus, - # instead of polluting +Thread.current+ - # - # Thread.current[:connection_handler] - # - # you write + # and invoke the declared instance accessors as class methods. So # - # ActiveRecord::RuntimeRegistry.instance.connection_handler + # ActiveRecord::RuntimeRegistry.connection_handler = connection_handler # - # A +method_missing+ handler that proxies to the thread local instance is - # installed in the extended class so the call above can be shortened to + # sets a connection handler local to the current thread, and # # ActiveRecord::RuntimeRegistry.connection_handler # - # The instance is stored as a thread local keyed by the name of the class, - # that is the string "ActiveRecord::RuntimeRegistry" in the example above. + # returns a connection handler local to the current thread. + # + # This feature is accomplished by instantiating the class and storing the + # instance as a thread local keyed by the class name. In the example above + # a key "ActiveRecord::RuntimeRegistry" is stored in <tt>Thread.current</tt>. + # The class methods proxy to said thread local instance. # # If the class has an initializer, it must accept no arguments. module PerThreadRegistry - def instance - Thread.current[self.name] ||= new - end - protected - def method_missing(*args, &block) - instance.public_send(*args, &block) + def method_missing(name, *args, &block) + # Caches the method definition as a singleton method of the receiver. + singleton_class.class_eval do + define_method(name) do |*a, &b| + per_thread_registry_instance.public_send(name, *a, &b) + end + end + + send(name, *args, &block) + end + + private + + def per_thread_registry_instance + Thread.current[name] ||= new end end end |