提交 b37399ab 编写于 作者: S Sam Saffron 提交者: Sam

Make connection_handler overridable per thread

上级 c56e6204
## Rails 4.0.0 (unreleased) ##
* Allow ActiveRecord::Base.connection_handler to have thread affinity and be
settable, this effectively allows ActiveRecord to be used in a multi threaded
setup with multiple connections to multiple dbs.
*Sam Saffron*
* `rename_column` preserves auto_increment in mysql migrations.
Fixes #3493.
......@@ -8,7 +14,7 @@
* PostgreSQL geometric type point is supported by ActiveRecord. Fixes #7324.
*Martin Schuerrer*
* Add suport for concurrent indexing in PostgreSQL adapter via the
`algorithm: :concurrently` option
......
......@@ -77,8 +77,17 @@ module Core
mattr_accessor :disable_implicit_join_references, instance_writer: false
self.disable_implicit_join_references = false
class_attribute :connection_handler, instance_writer: false
self.connection_handler = ConnectionAdapters::ConnectionHandler.new
class_attribute :default_connection_handler, instance_writer: false
def self.connection_handler
Thread.current[:active_record_connection_handler] || self.default_connection_handler
end
def self.connection_handler=(handler)
Thread.current[:active_record_connection_handler] = handler
end
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
end
module ClassMethods
......
......@@ -1578,4 +1578,61 @@ def test_default_values_are_deeply_dupped
klass = Class.new(ActiveRecord::Base)
assert_equal ['foo'], klass.all.merge!(select: 'foo').select_values
end
test "connection_handler can be overriden" do
klass = Class.new(ActiveRecord::Base)
orig_handler = klass.connection_handler
new_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
thread_connection_handler = nil
t = Thread.new do
klass.connection_handler = new_handler
thread_connection_handler = klass.connection_handler
end
t.join
assert_equal klass.connection_handler, orig_handler
assert_equal thread_connection_handler, new_handler
end
test "new threads get default the default connection handler" do
klass = Class.new(ActiveRecord::Base)
orig_handler = klass.connection_handler
handler = nil
t = Thread.new do
handler = klass.connection_handler
end
t.join
assert_equal handler, orig_handler
assert_equal klass.connection_handler, orig_handler
assert_equal klass.default_connection_handler, orig_handler
end
test "changing a connection handler in a main thread does not poison the other threads" do
klass = Class.new(ActiveRecord::Base)
orig_handler = klass.connection_handler
new_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
after_handler = nil
is_set = false
t = Thread.new do
klass.connection_handler = new_handler
is_set = true
Thread.stop
after_handler = klass.connection_handler
end
while(!is_set)
Thread.pass
end
klass.connection_handler = orig_handler
t.wakeup
t.join
assert_equal after_handler, new_handler
assert_equal orig_handler, klass.connection_handler
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册