Skip to content
This repository
Browse code

Make connection_handler overridable per thread

  • Loading branch information...
commit b37399ab987c3f54e94178da7d41bfc5f48308de 1 parent c56e620
Sam authored March 27, 2013
8  activerecord/CHANGELOG.md
Source Rendered
... ...
@@ -1,5 +1,11 @@
1 1
 ## Rails 4.0.0 (unreleased) ##
2 2
 
  3
+*   Allow ActiveRecord::Base.connection_handler to have thread affinity and be
  4
+    settable, this effectively allows ActiveRecord to be used in a multi threaded
  5
+    setup with multiple connections to multiple dbs.
  6
+
  7
+    *Sam Saffron*
  8
+
3 9
 *   `rename_column` preserves auto_increment in mysql migrations.
4 10
     Fixes #3493.
5 11
 
@@ -8,7 +14,7 @@
8 14
 *   PostgreSQL geometric type point is supported by ActiveRecord. Fixes #7324.
9 15
 
10 16
     *Martin Schuerrer*
11  
- 
  17
+
12 18
 *   Add suport for concurrent indexing in PostgreSQL adapter via the
13 19
     `algorithm: :concurrently` option
14 20
 
13  activerecord/lib/active_record/core.rb
@@ -77,8 +77,17 @@ module Core
77 77
       mattr_accessor :disable_implicit_join_references, instance_writer: false
78 78
       self.disable_implicit_join_references = false
79 79
 
80  
-      class_attribute :connection_handler, instance_writer: false
81  
-      self.connection_handler = ConnectionAdapters::ConnectionHandler.new
  80
+      class_attribute :default_connection_handler, instance_writer: false
  81
+      
  82
+      def self.connection_handler
  83
+        Thread.current[:active_record_connection_handler] || self.default_connection_handler
  84
+      end
  85
+
  86
+      def self.connection_handler=(handler)
  87
+        Thread.current[:active_record_connection_handler] = handler
  88
+      end
  89
+
  90
+      self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
82 91
     end
83 92
 
84 93
     module ClassMethods
57  activerecord/test/cases/base_test.rb
@@ -1578,4 +1578,61 @@ def test_default_values_are_deeply_dupped
1578 1578
     klass = Class.new(ActiveRecord::Base)
1579 1579
     assert_equal ['foo'], klass.all.merge!(select: 'foo').select_values
1580 1580
   end
  1581
+
  1582
+  test "connection_handler can be overriden" do
  1583
+    klass = Class.new(ActiveRecord::Base)
  1584
+    orig_handler = klass.connection_handler
  1585
+    new_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
  1586
+    thread_connection_handler = nil
  1587
+
  1588
+    t = Thread.new do
  1589
+      klass.connection_handler = new_handler
  1590
+      thread_connection_handler = klass.connection_handler
  1591
+    end
  1592
+    t.join
  1593
+
  1594
+    assert_equal klass.connection_handler, orig_handler
  1595
+    assert_equal thread_connection_handler, new_handler
  1596
+  end
  1597
+
  1598
+  test "new threads get default the default connection handler" do
  1599
+    klass = Class.new(ActiveRecord::Base)
  1600
+    orig_handler = klass.connection_handler
  1601
+    handler = nil
  1602
+
  1603
+    t = Thread.new do
  1604
+      handler = klass.connection_handler
  1605
+    end
  1606
+    t.join
  1607
+
  1608
+    assert_equal handler, orig_handler
  1609
+    assert_equal klass.connection_handler, orig_handler
  1610
+    assert_equal klass.default_connection_handler, orig_handler
  1611
+  end
  1612
+
  1613
+  test "changing a connection handler in a main thread does not poison the other threads" do
  1614
+    klass = Class.new(ActiveRecord::Base)
  1615
+    orig_handler = klass.connection_handler
  1616
+    new_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
  1617
+    after_handler = nil
  1618
+    is_set = false
  1619
+
  1620
+    t = Thread.new do
  1621
+      klass.connection_handler = new_handler
  1622
+      is_set = true
  1623
+      Thread.stop
  1624
+      after_handler = klass.connection_handler
  1625
+    end
  1626
+
  1627
+    while(!is_set)
  1628
+      Thread.pass
  1629
+    end
  1630
+
  1631
+    klass.connection_handler = orig_handler
  1632
+    t.wakeup
  1633
+    t.join
  1634
+
  1635
+    assert_equal after_handler, new_handler
  1636
+    assert_equal orig_handler, klass.connection_handler
  1637
+  end
1581 1638
 end

0 notes on commit b37399a

Please sign in to comment.
Something went wrong with that request. Please try again.