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 6bc953f commit be68811aaa4c75a032df72b11d07b10446b4d0ac
@@ -637,7 +637,7 @@ def pool_for(owner)
end
def pool_from_any_process_for(owner)
- owner_to_pool = @owner_to_pool.values.find { |v| v[owner.name] }
+ owner_to_pool = @owner_to_pool.values.reverse.find { |v| v[owner.name] }
owner_to_pool && owner_to_pool[owner.name]
end
end
@@ -48,6 +48,41 @@ def test_connection_pools
assert_equal({ Base.connection_pool.spec => @pool }, @handler.connection_pools)
end
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
end
end
end

0 comments on commit be68811

Please sign in to comment.