I have a setup where Rails 5 / Ruby 2.4.1 MRI application requires a connection to two databases, both on the same PostgreSQL instance, one shared between all users, one picked based on authenticated user. Both databases have connection pooling set to 5 connections.
I'm using base ActiveRecord classes for both cases, one something like
class Base1 < ActiveRecord::Base
self.abstract_class = true
establish_connection "base1_#{Rails.env}".to_sym
end
class Base2 < ActiveRecord::Base
self.abstract_class = true
establish_connection "base2_#{Rails.env}".to_sym
end
To dynamically select database per user I have before_action block in ApplicationController doing
dbconf = Base2.configurations[Rails.env].dup
dbconf['database'] = current_user.db
Base2.establish_connection(dbconf)
This seemed to work under Rails 4.2 single process per request model but after switching to Rails 5 / Puma I get occasional errors where queries related to classes inherited from Base2 fail. Puma has to run at least with two threads and requests have to come in parallel for the error to occur. Some debugging shows Base2ChildClass.connection.current_database to be the one specified for Base1.
Is it some (almost) known error in ActiveRecord connection pooling? Is my approach to db switching valid? I would understand if thread safety violations would mix up different db instances under Base2 but how on earth could Base2 child classes get Base1 connection into their hands?