Skip to content

Commit

Permalink
Avoid getting a connection to the database before it's necessary
Browse files Browse the repository at this point in the history
We init the first time we request a connection. On code reloads, we
"forget" about our init state and we call it again.

After init, ensure the search path is set properly
  • Loading branch information
fsateler committed May 14, 2020
1 parent 8439fc4 commit 256de6f
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 21 deletions.
6 changes: 6 additions & 0 deletions lib/apartment/adapters/abstract_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ def create(tenant)
end
end

# Initialize Apartment config options such as excluded_models
#
def init
process_excluded_models
end

# Note alias_method here doesn't work with inheritence apparently ??
#
def current
Expand Down
5 changes: 5 additions & 0 deletions lib/apartment/adapters/postgresql_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ def reset
Apartment.connection.schema_search_path = full_search_path
end

def init
super
Apartment.connection.schema_search_path = full_search_path
end

def current
@current || default_tenant
end
Expand Down
27 changes: 12 additions & 15 deletions lib/apartment/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,23 @@ class Railtie < Rails::Railtie
ActiveRecord::Migrator.migrations_paths = Rails.application.paths['db/migrate'].to_a
end

# Hook into ActionDispatch::Reloader to ensure Apartment is properly initialized
# Note that this doens't entirely work as expected in Development, because this is called before classes are reloaded
# See the middleware/console declarations below to help with this. Hope to fix that soon.
#
# Make sure Apartment is reconfigured when the code is reloaded
config.to_prepare do
next if ARGV.any? { |arg| arg =~ /\Aassets:(?:precompile|clean)\z/ }
next if ARGV.any? { |arg| arg == 'webpacker:compile' }
Apartment::Tenant.reinitialize
end

begin
Apartment.connection_class.connection_pool.with_connection do
Apartment::Tenant.init
end
rescue ::ActiveRecord::NoDatabaseError, PG::ConnectionBad
# Since `db:create` and other tasks invoke this block from Rails 5.2.0,
# we need to swallow the error to execute `db:create` properly.
Rails.logger.warn do
'Failed to initialize Apartment because a database connection could not be established.'
#
# Ensure that Apartment::Tenant.init is called when
# a new connection is requested.
#
module ApartmentInitializer
def connection
super.tap do
Apartment::Tenant.init_once
end
end
end
ActiveRecord::Base.singleton_class.prepend ApartmentInitializer

#
# Ensure rake tasks are loaded
Expand Down
19 changes: 14 additions & 5 deletions lib/apartment/tenant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,23 @@ module Tenant
extend Forwardable

def_delegators :adapter, :create, :drop, :switch, :switch!, :current, :each,
:reset, :set_callback, :seed, :current_tenant,
:reset, :init, :set_callback, :seed, :current_tenant,
:default_tenant, :environmentify

attr_writer :config

# Initialize Apartment config options such as excluded_models
#
def init
adapter.process_excluded_models
def init_once
return if @already_initialized

# To avoid infinite loops in work init is doing,
# we need to set @already_initialized to true
# before init is called
@already_initialized = true
init
end

def reinitialize
@already_initialized = false
end

# Fetch the proper multi-tenant adapter based on Rails config
Expand Down Expand Up @@ -53,6 +61,7 @@ def adapter
#
def reload!(config = nil)
Thread.current[:apartment_adapter] = nil
reinitialize
@config = config
end

Expand Down
2 changes: 1 addition & 1 deletion spec/examples/generic_adapter_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
.instance_variable_get(:@queue)
.size

expect(num_available_connections).to eq(1)
expect(num_available_connections).to eq(0)
end
end
end
Expand Down

0 comments on commit 256de6f

Please sign in to comment.