Permalink
Browse files

Fix pool_from_any_process to use most recent spec

If a process is forked more than once, the pool was grabbing the oldest
spec, not the most recent spec. This wasn't noticed before because most
folks are lilely forking the process only once.

If you're forking the process multiple times however the wrong spec name
will be returned and an incorrect connection will be used for the
process.

This fixes the issue by reversing the list of spec names so we can grab
the most recent spec rather than the oldest spec.
  • Loading branch information...
1 parent f2ef515 commit e15a23fa355ed29d70c2ec573cd7b2418f7ac8db @eileencodes eileencodes committed Jan 14, 2017
@@ -967,7 +967,7 @@ def owner_to_pool
end
def pool_from_any_process_for(spec_name)
- owner_to_pool = @owner_to_pool.values.find { |v| v[spec_name] }
+ owner_to_pool = @owner_to_pool.values.reverse.find { |v| v[spec_name] }
owner_to_pool && owner_to_pool[spec_name]
end
end
@@ -89,6 +89,41 @@ def test_retrieve_connection_pool_copies_schema_cache_from_ancestor_pool
rd.close
end
+ def test_pool_from_any_process_for_uses_most_recent_spec
+ skip unless current_adapter?(:SQLite3Adapter)
+
+ file = Tempfile.new "lol.sqlite3"
+
+ rd, wr = IO.pipe
+ rd.binmode
+ wr.binmode
+
+ pid = fork do
+ ActiveRecord::Base.configurations["arunit"]["database"] = file.path
+ ActiveRecord::Base.establish_connection(:arunit)
+
+ pid2 = fork do
+ wr.write ActiveRecord::Base.connection_config[:database]
+ wr.close
+ end
+
+ Process.waitpid pid2
+ end
+
+ Process.waitpid pid
+
+ wr.close
+
+ assert_equal file.path, rd.read
+
+ rd.close
+ ensure
+ if file
+ file.close
+ file.unlink
+ end
+ end
+
def test_a_class_using_custom_pool_and_switching_back_to_primary
klass2 = Class.new(Base) { def self.name; "klass2"; end }

0 comments on commit e15a23f

Please sign in to comment.