Skip to content

Commit

Permalink
Refactor SchemaCache to hold a ConnectionPool
Browse files Browse the repository at this point in the history
Another refactoring in relation to rails#50793

But it makes sense even without it.

Rather than each connection to have its own `BoundSchemaReflection`,
we can instead have `BoundSchemaReflection` hold a `ConnectionPool`,
from which it can checkout a connection to perform queries when needed.

If the current thread already leased a connection, it will be used.

This simplifies the interface quite a bit.
  • Loading branch information
byroot authored and viralpraxis committed Mar 24, 2024
1 parent df58d94 commit c5b022d
Show file tree
Hide file tree
Showing 22 changed files with 189 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def get_primary_key(base_name) # :nodoc:
elsif base_name && primary_key_prefix_type == :table_name_with_underscore
base_name.foreign_key
elsif ActiveRecord::Base != self && table_exists?
connection.schema_cache.primary_keys(table_name)
schema_cache.primary_keys(table_name)
else
"id"
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def schema_reflection
SchemaReflection.new(nil)
end

def schema_cache; end
def connection_class; end
def checkin(_); end
def remove(_); end
Expand Down Expand Up @@ -117,7 +118,7 @@ class ConnectionPool
include ConnectionAdapters::AbstractPool

attr_accessor :automatic_reconnect, :checkout_timeout
attr_reader :db_config, :size, :reaper, :pool_config, :async_executor, :role, :shard
attr_reader :db_config, :size, :reaper, :pool_config, :async_executor, :role, :shard, :schema_cache

delegate :schema_reflection, :schema_reflection=, :server_version, to: :pool_config

Expand Down Expand Up @@ -166,6 +167,8 @@ def initialize(pool_config)

@async_executor = build_async_executor

@schema_cache = BoundSchemaReflection.new(schema_reflection, self)

@reaper = Reaper.new(self, db_config.reaping_frequency)
@reaper.run
end
Expand Down Expand Up @@ -588,6 +591,7 @@ def attempt_to_checkout_all_existing_connections(raise_on_acquisition_timeout =
loop do
synchronize do
return if collected_conns.size == @connections.size && @now_connecting == 0

remaining_timeout = timeout_time - Process.clock_gettime(Process::CLOCK_MONOTONIC)
remaining_timeout = 0 if remaining_timeout < 0
conn = checkout_for_exclusive_access(remaining_timeout)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ def pool=(value)
@schema_cache = nil
@pool = value

@pool.schema_reflection.load!(self) if ActiveRecord.lazily_load_schema_cache
if @pool && ActiveRecord.lazily_load_schema_cache
@pool.schema_reflection.load!(@pool)
end
end

set_callback :checkin, :after, :enable_lazy_transactions!
Expand Down Expand Up @@ -321,7 +323,7 @@ def shard
end

def schema_cache
@schema_cache ||= BoundSchemaReflection.new(@pool.schema_reflection, self)
@pool.schema_cache || (@schema_cache ||= BoundSchemaReflection.for_lone_connection(@pool.schema_reflection, self))
end

# this method must only be called while holding connection pool's mutex
Expand Down

0 comments on commit c5b022d

Please sign in to comment.