Active recording and multi-threading with multiple dbs

I have a Rails application that is multi-use.

foo.mysite.com talking to "foo" db.

bar.mysite.com talking to "bar" db.

This is achieved by calling:

ActiveRecord::Base.connection_handler.establish_connection("ActiveRecord::Base", foo_spec)

When requests come to foo, it uses foo_spec, when requests come to bar, it uses bar_spec.

Everything is happy and peace in the world.

but

I also use sidekiq , it is very multithreaded.

I was getting weird behavior in sidekiq. Often, when I thought I was talking to foo_db, ActiveRecord::Base.connection was specified in bar_db.

I dug up the code and found:

  def retrieve_connection_pool(klass) pool = @class_to_pool[klass.name] return pool if pool return nil if ActiveRecord::Base == klass retrieve_connection_pool klass.superclass end 

It turns out that the internal construction of AR allows AR :: Base to know about one connection pool.

Is there a way to get thread 1 to talk to db1, and thread 2 to talk to db2 at the same time using ActiveRecord::Base.connection ?

+4
source share
1 answer

I would recommend using Postgres and separate schemas, rather than separate databases as a whole; you could share pools.

Usage will look like this: select * from foo.users , select * from bar.users

And you pass the circuit to your background worker as an argument.

-1
source

All Articles