ActiveRecord::Base.establish_connection does not use the connection pool #7019

Closed
SamSaffron opened this Issue Jul 10, 2012 · 12 comments

Projects

None yet

7 participants

@SamSaffron
Contributor

Due to a new resolver being spun up and a new spec generated, ActiveRecord::Base.establish_connection does not make use of the connection pool at all.

Work around is to do:

resolver = ActiveRecord::Base::ConnectionSpecification::Resolver.new config, ActiveRecord::Base.configurations
ActiveRecord::Base.connection_handler.establish_connection config, resolver.spec

@carlosantoniodasilva

Sorry, can you please clarify the code (use Github Flavored Markdown to style it so we can better read it), and tell us the Rails version you're using? Thanks!

@SamSaffron
Contributor

Using Rails 3.2.6

# this works and uses the pool
resolver = ActiveRecord::Base::ConnectionSpecification::Resolver.new "production", ActiveRecord::Base.configurations
ActiveRecord::Base.connection_handler.establish_connection "production", resolver.spec

# this works but does not use the pool
ActiveRecord::Base.establish_connection "production" 
@SamSaffron
Contributor

It actually is a bit worse ... "seems" the correct thing to do is:

# ActiveRecord::Base.remove_connection # don't ever call this cause it nukes the pool 
resolver = ActiveRecord::Base::ConnectionSpecification::Resolver.new "someconfig", ActiveRecord::Base.configurations
spec = resolver.spec # cache this across calls ... 
ActiveRecord::Base.connection_handler.establish_connection "ActiveRecord::Base", spec
@BMorearty
Contributor

@SamSaffron is correct. If multiple tables call establish_connection independently, but using the same connection key, each table will end up with its own connection pool. Starting in 3.2, errors will occur.

I wrote up some details of it in a blog post where I tried to explain how people can make their establish_connection calls work again in 3.2.

The culprit seems to be the first line of this method in ActiveRecord::ConnectionAdapters::ConnectionHandler:

      def establish_connection(name, spec)
        @connection_pools[spec] ||= ConnectionAdapters::ConnectionPool.new(spec)
        @class_to_pool[name] = @connection_pools[spec]
      end

@connection_pools[spec] will always be nil because every time ActiveRecord::Base::establish_connection is called, a new ConnectionSpecification::Resolver is created. That resolver gets passed in as the spec param, so you're guaranteed that @connection_pools[some newly created spec] will be nil...and it will create a new pool.

@fingermark

Just got bit by this pretty hard. So, I applied the suggestions by @BMorearty to subclass AR::Base. And got bit by #5872. So I'm on rails 3-2-stable. So far so good: no prepared statement errors and no connections going out of control (with BMorearty's code change suggestions). Weird thing is I have a pool size of 1 with 4 unicorn workers. My default database has 4 db connections (also w/ a pool size of 1). My non-default db only has 1. I was expecting 4 like I have with my default, since I have 4 workers.

@fingermark

@jonleighton do you know if your recent connection pool and connection handler refactoring addressed this?

@jonleighton
Member

I don't know. Please feel free to try master and update the ticket, but this sounds bad so I'll try to find time to take a look.

@jonleighton
Member

Looking into this a bit more, I don't think this is actually a bug. What's described here is how it's designed to work: every time you call establish_connection you create a new pool. Therefore, if you want to share pools between classes you should use an abstract superclass.

@BMorearty
Contributor

Thanks for looking at it, @jonleighton. Much appreciated. I guess the fact that it seemed to "work" (before 3.2) was a bug--those of us who didn't know we were doing it wrong were just getting lucky.

@himanshu-saxena

Hi All,
Can you please guide me , how can I use two database in same development environment

Thanks

@robin850
Member

@mobiloitte : Could you ask your question on the rubyonrails-talk mailing list please ? This is not really the place for such questions. Thank you!

@apneadiving apneadiving referenced this issue in influitive/apartment Oct 7, 2015
Closed

transactions and different db servers #264

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment