Context
I'm building a SaaS where users can create their own websites (like Wix or SquareSpace). That's what happens behind scenes:
- My app has its main database which stores users
- When a user creates his website, an external database is created to store its data
- SQL file runs in this external database to set default settings
- Other users shall create their websites simultaneously
Approach
To create a new database and establish connection I do the following:
ActiveRecord::Base.connection.execute("CREATE DATABASE #{name}")
ActiveRecord::Base.establish_connection(<dynamic db data>)
Then I execute sql code in the db by doing:
sql = File.read(sql_file.sql)
statements = sql.split(/;$/)
statements.pop
ActiveRecord::Base.transaction do
statements.each do |statement|
connection.execute(statement)
end
end
Then I reestablish connection with main db:
ActiveRecord::Base.establish_connection :production
Problem
- Establishing connection to dynamic database makes application's main database inacessible for a while:
- User A is creating a website (establishes dynamic database connection)
- User B tries to access his user area (which requires application's main db data)
- Application throws an error because it tries to retrieve data of app-main-db (which connection is not established at the moment)
How can I handle many users creating their websites simultaneously without databases conflict?
In other words, how can I establish_connection
with more than one database in parallel?
NOTE: It is not the same as connecting to multiple databases through database.yml. The goal here is to connect and disconnect to dynamic created databases by multiple users simultaneously.