概要
Rails v7.1で改修があったスキーマキャッシュ周りのSchemaCache, BoundSchemaReflection, SchemaReflectionの3つのクラスについての解説があまりなかったので、調査した。
version
at: Rails v7.2.1 https://github.com/rails/rails/releases/tag/v7.2.1
SchemaCache, BoundSchemaReflection, SchemaReflectionについて
ConnectionPool
はApplicationRecordクラスなどに設定したrole, databaseごとに存在している。
ConnectionPool
が @schema_cache
を持っているのでこれを手がかりに調べる。
class ConnectionPool ... attr_accessor :automatic_reconnect, :checkout_timeout attr_reader :db_config, :size, :reaper, :pool_config, :async_executor, :role, :shard delegate :schema_reflection, :server_version, to: :pool_config ... def initialize(pool_config) ... @schema_cache = nil ... end def schema_cache # pool_configにschema_reflectionがdelegateされている @schema_cache ||= BoundSchemaReflection.new(schema_reflection, self) end def schema_reflection=(schema_reflection) # pool_configにschema_reflectionを設定している pool_config.schema_reflection = schema_reflection @schema_cache = nil end ... end
delegate先のPoolConfig
を見る。
rails/activerecord/lib/active_record/connection_adapters/pool_config.rb at v7.2.1 · rails/rails
class PoolConfig # :nodoc: include MonitorMixin attr_reader :db_config, :role, :shard attr_writer :schema_reflection, :server_version attr_accessor :connection_class # ConnectionPoolからのdelegate先 def schema_reflection @schema_reflection ||= SchemaReflection.new(db_config.lazy_schema_cache_path) end ... end
lazy_schema_cache_pathはHashConfigにある
rails/activerecord/lib/active_record/database_configurations/hash_config.rb at v7.2.1 · rails/rails
# The path to the schema cache dump file for a database. If omitted, the # filename will be read from ENV or a default will be derived. def schema_cache_path # 設定してたら、優先される configuration_hash[:schema_cache_path] end def default_schema_cache_path(db_dir = "db") if primary? File.join(db_dir, "schema_cache.yml") else File.join(db_dir, "#{name}_schema_cache.yml") end end def lazy_schema_cache_path schema_cache_path || default_schema_cache_path end
まとめ
ConnectionPool
がスキーマキャッシュを保持していると考えて良い。正確に言うとConnectionPool
はBoundSchemaReflection
を保持しているConnectionPool
が保持しているBoundSchemaReflection
には、ConnectionPool
に紐づくPoolConfig
のSchemaReflection
が入るSchemaReflection
BoundSchemaReflection
*ConnectionPool
とSchemaReflection
の橋渡し役- attrs
- schema_reflection: 上記の
SchemaReflection
- pool:
ConnectionPool
のPoolConfig
- schema_reflection: 上記の
- attrs
- スキーマキャッシュは
BoundSchemaReflection
->SchemaReflection
->SchemaCache
の3つで構成するイメージ