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...
eileencodes committed Jan 14, 2017
1 parent f2ef515 commit e15a23fa355ed29d70c2ec573cd7b2418f7ac8db
@@ -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.