veader, the codemonky

ramblings, musing and code snippets
Mar 18
Permalink

establish_connection may harm you

So I have a reporting Rails application that is looking at the databases of two other Rails apps. I import the models using an svn:external link. I then have initializers that do a bit of “magic” switching which databases the models use and what their table names are based on the schema. We use Postgres so the “databases” are actually schemas in the same physical database.

unless RAILS_ENV.downcase == 'test'
# point all of the vanguard models to the champion_#{RAILS_ENV} database
Dir[File.expand_path('app/models/vanguard/*.rb',RAILS_ROOT)].each do |file|
model_str = $1.classify if file =~ /\/vanguard\/(.*?)\.rb$/

next unless model_str
# skip the models that aren't active record models
next if %w(...).include?(model_str)

eval("#{model_str}.instance_eval('establish_connection \"champion_#{RAILS_ENV}\"')")
table_name = eval("#{model_str}.table_name")
eval("#{model_str}.instance_eval('set_table_name \"vanguard.#{table_name}\"')")
end
end

I kept running into a problem where the maximum number of connections to this database was being exceeded. After poking around some I believe establish_connection isn’t doing the smart thing. It seems to blindly establish a connection each time it is called disregarding the fact that the connection might already be open.

I switched the logic such that the “primary” database is now this external connection and sub-class all of my internal models to use an abstract ActiveRecord class that points to a different database. The number of connections has dropped significantly.