diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2013-04-09 21:27:48 -0700 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2013-04-09 21:27:48 -0700 |
commit | e0af93dd3a5eeee2e2a67b05f34afb66cc80c00b (patch) | |
tree | 5bcd2ef9f09cc031f54f9475ec28c9f0e6b4c4e1 /activerecord | |
parent | 9039c5038823754f79e04f1e83723e46229dbe05 (diff) | |
parent | e12901e4235d1ece2a17c5419f4420f1931cc6a4 (diff) | |
download | rails-e0af93dd3a5eeee2e2a67b05f34afb66cc80c00b.tar.gz rails-e0af93dd3a5eeee2e2a67b05f34afb66cc80c00b.tar.bz2 rails-e0af93dd3a5eeee2e2a67b05f34afb66cc80c00b.zip |
Merge pull request #10156 from wangjohn/grouping_thread_locals
Grouping thread locals in ActiveRecord
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record.rb | 1 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_handling.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/core.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/log_subscriber.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/runtime_registry.rb | 32 | ||||
-rw-r--r-- | activerecord/lib/active_record/scoping.rb | 12 | ||||
-rw-r--r-- | activerecord/test/cases/base_test.rb | 4 |
7 files changed, 47 insertions, 14 deletions
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 3bfc6772b2..249eabfd7d 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -50,6 +50,7 @@ module ActiveRecord autoload :Querying autoload :ReadonlyAttributes autoload :Reflection + autoload :RuntimeRegistry autoload :Sanitization autoload :Schema autoload :SchemaDumper diff --git a/activerecord/lib/active_record/connection_handling.rb b/activerecord/lib/active_record/connection_handling.rb index 1e03414c29..3f175988db 100644 --- a/activerecord/lib/active_record/connection_handling.rb +++ b/activerecord/lib/active_record/connection_handling.rb @@ -54,11 +54,11 @@ module ActiveRecord end def connection_id - Thread.current['ActiveRecord::Base.connection_id'] + ActiveRecord::RuntimeRegistry.instance.connection_id end def connection_id=(connection_id) - Thread.current['ActiveRecord::Base.connection_id'] = connection_id + ActiveRecord::RuntimeRegistry.instance.connection_id = connection_id end # Returns the configuration of the associated connection as a hash: diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index afa1766615..7a8408155a 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -80,11 +80,11 @@ module ActiveRecord class_attribute :default_connection_handler, instance_writer: false def self.connection_handler - Thread.current[:active_record_connection_handler] || self.default_connection_handler + ActiveRecord::RuntimeRegistry.instance.connection_handler || self.default_connection_handler end def self.connection_handler=(handler) - Thread.current[:active_record_connection_handler] = handler + ActiveRecord::RuntimeRegistry.instance.connection_handler = handler end self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new diff --git a/activerecord/lib/active_record/log_subscriber.rb b/activerecord/lib/active_record/log_subscriber.rb index c1ba524c84..69371a1dab 100644 --- a/activerecord/lib/active_record/log_subscriber.rb +++ b/activerecord/lib/active_record/log_subscriber.rb @@ -3,11 +3,11 @@ module ActiveRecord IGNORE_PAYLOAD_NAMES = ["SCHEMA", "EXPLAIN"] def self.runtime=(value) - Thread.current[:active_record_sql_runtime] = value + ActiveRecord::RuntimeRegistry.instance.sql_runtime = value end def self.runtime - Thread.current[:active_record_sql_runtime] ||= 0 + ActiveRecord::RuntimeRegistry.instance.sql_runtime ||= 0 end def self.reset_runtime diff --git a/activerecord/lib/active_record/runtime_registry.rb b/activerecord/lib/active_record/runtime_registry.rb new file mode 100644 index 0000000000..3f0ac68143 --- /dev/null +++ b/activerecord/lib/active_record/runtime_registry.rb @@ -0,0 +1,32 @@ +require 'active_support/per_thread_registry' + +module ActiveRecord + # This is a registry class for storing local variables in active record. The + # class allows you to access variables that are local to the current thread. + # These thread local variables are stored as attributes in the + # +RuntimeRegistry+ class. + # + # You can access the thread local variables by calling a variable's name on + # the +RuntimeRegistry+ class. For example, if you wanted to obtain the + # connection handler for the current thread, you would invoke: + # + # ActiveRecord::RuntimeRegistry.instance.connection_handler + # + # The +PerThreadRegistry+ module will make a new +RuntimeRegistry+ instance + # and store it in +Thread.current+. Whenever you make a call for an attribute + # on the +RuntimeRegistry+ class, the call will be sent to the instance that + # is stored in +Thread.current+. + # + # Note that you can also make the following call which would provide an + # equivalent result as the previous code: + # + # ActiveRecord::RuntimeRegistry.connection_handler + # + # However, this is less performant because it makes a call to +method_missing+ + # before it sends the method call to the +instance+. + class RuntimeRegistry + extend ActiveSupport::PerThreadRegistry + + attr_accessor :connection_handler, :sql_runtime, :connection_id + end +end diff --git a/activerecord/lib/active_record/scoping.rb b/activerecord/lib/active_record/scoping.rb index f108ab0fe0..6ab36a23a7 100644 --- a/activerecord/lib/active_record/scoping.rb +++ b/activerecord/lib/active_record/scoping.rb @@ -1,3 +1,5 @@ +require 'active_support/per_thread_registry' + module ActiveRecord module Scoping extend ActiveSupport::Concern @@ -34,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.current + # registry = ActiveRecord::Scoping::ScopeRegistry.instance # registry.set_value_for(:current_scope, "Board", some_new_scope) # # Now when you run: @@ -48,12 +50,10 @@ module ActiveRecord # ActiveRecord::Scoping::ScopeRegistry.set_value_for(:current_scope, # "Board", some_new_scope) class ScopeRegistry # :nodoc: - class << self - delegate :value_for, :set_value_for, to: :current + extend ActiveSupport::PerThreadRegistry - def current - Thread.current["scope_registry"] ||= new - end + class << self + delegate :value_for, :set_value_for, to: :instance end VALID_SCOPE_TYPES = [:current_scope, :ignore_default_scope] diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index e57dbd5a09..83fc0b48f9 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.current.value_for(:current_scope, "UnloadablePost") + assert_not_nil ActiveRecord::Scoping::ScopeRegistry.instance.value_for(:current_scope, "UnloadablePost") ActiveSupport::Dependencies.remove_unloadable_constants! - assert_nil ActiveRecord::Scoping::ScopeRegistry.current.value_for(:current_scope, "UnloadablePost") + assert_nil ActiveRecord::Scoping::ScopeRegistry.instance.value_for(:current_scope, "UnloadablePost") ensure Object.class_eval{ remove_const :UnloadablePost } if defined?(UnloadablePost) end |