简体   繁体   中英

How to configure schema cache for rails 5 app?

So, I'm currently using Rails 5 and a mysql db on a project. I'm trying to use the ActiveRecord Schema Cache to eager load tables on my rails application without the need to query show full fields . This option is enabled by default and to make it work the only thing you need to do is use the rake db:schema:cache:dump (which will generate the cache file in the db folder). Although, I kept seeing that show full fields query was triggering through newrelic and decided to run some testes to assess if the cache was working.

After a few tests I've stated the the cache was indeed not working and was left without a clue of what was happening. I tried to set the active_record.use_schema_cache_dump option as true in the configurations and made sure the schema cache file was present on the application folder. After that I decided to initialize the cache manually in my application and using a binding.pry to see how it was going. The interesting thing is that the cache was loaded and the connections were stablished without querying on the context, but as sson as I left pry and the server started the cache was unloaded.

I noticed another curious thing, the problema wasn't that the cache had been cleaned, it was that the connection used by ActiveRecord was a differente object on both steps.

This one was my custom initializer (adapted from here ):

ActiveSupport.on_load(:active_record) do
  filename = File.join(Rails.application.config.paths["db"].first, "schema_cache.yml")

  if File.file?(filename)
    current_version = ActiveRecord::Migrator.current_version

    next if current_version.nil?

    cache = YAML.load(File.read(filename))
    if cache.version == current_version
      ActiveRecord::Base.connection.schema_cache = cache
      ActiveRecord::Base.connection_pool.schema_cache = cache.dup
      binding.pry
    else
      warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
    end
  end
end

And on the console I used:

[1] pry(ActiveRecord::Base)> ActiveRecord::Base.connection.object_id
=> 70357693731960

Running via Spring preloader in process 21185
Loading development environment (Rails 5.2.2.1)

Frame number: 0/25
[1] pry(main)> ActiveRecord::Base.connection.object_id
(4.3ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
=> 70357724355600

As shown above the connection objects a different from the initialization and the console itself, same happens for server. Because of that the schema_cache from the connection is empty.

Can anyone clarify to me whats wrong with my hypothesis or point me on the right direction to perform the schema caching?

I found the solution. Puma was the one to blame, not Rails. The ActiveRecord connection was being lost after puma forked a worker.

Issue describing the problem

Pull request on Rails stating that the puma configuration was no longer necessary

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM