Search code examples
ruby-on-railsrubymultithreadingactiverecordsequel

Multiple connections in a Sequel Connection pool


I have a Ruby on Rails app where users connect to a different database than what is set in config/database.yml. Possible database connections are stored in a table in the database. The database connection is set on each request by calling establish_connection(connection_config) on the ActiveRecord model

I tried to do something similar with Sequel using the following code

  def self.establish_sequel_connection group
    found = Sequel::DATABASES.find { |db| database_equal_group? db, group }
    found || connect_to_group(group)
  end

  def self.connect_to_group(group)
    db = Sequel.connect(
      adapter: 'postgres', host: group['host'], database: group['database'],
      user: group['username'], password: group['password']
    )
    if Rails.env.development?
      db.sql_log_level = :info
      db.loggers.push(Logger.new($stdout))
    end
    db
  end

  def self.database_equal_group?(db, group)
    db[:host] == group[:host] && db[:database] == group[:database]
  end

When I used Sequel.connect multiple times, I watched multiple database I watched multiple connections get created in PgAdmin 4. When I used establish_sequel_connection in the console, it looked like only one connection was getting created. A little while after pushing it to production the db server got overloaded because of too many connections. What could've caused multiple connections to the same database if Sequel::DATABASES is a constant? Is it a multi-threading issue because establish_sequel_connection is called by multiple requests simultaneously?


Solution

  • One issue you may be having is that if group is a plain hash, then group['host'] and group[:host] are not the same thing. You may want to modify database_equal_group? to account for that.

    If all databases use the same schema, you may want to look into using Sequel's sharding support instead of creating multiple Sequel::Database instances.