Write Software, Well

September 30, 2023

What Happens When You Run Rails dev:cache Command?

The rails dev:cache command toggles caching in development.

By default, Rails enables caching only in production environment. To enable it in the development mode, you can run rails dev:cache command. To disable it, re-run the command.

$ bin/rails dev:cache
Development mode is now being cached.

$ bin/rails dev:cache
Development mode is no longer being cached.

Behind the scenes, it's implemented as a Thor command that delegates to the Rails::DevCaching module.

# railties/lib/rails/commands/dev/dev_command.rb

require "rails/dev_caching"

module Rails
module Command
class DevCommand < Base
desc "cache", "Toggle development mode caching on/off"
def cache
Rails::DevCaching.enable_by_file
end
end
end
end

The DevCaching::enable_by_file method does the following:

  1. Create a tmp directory if it doesn't exist.
  2. If the caching file (named caching-dev.txt) is present inside the tmp directory, it means caching is enabled. Delete that file to disable it. Otherwise, create it to enable caching.
  3. Finally, touch the restart.txt file to instruct Rails to restart the app.
# railties/lib/rails/dev_caching.rb

require "fileutils"

module Rails
module DevCaching
class << self
FILE = "tmp/caching-dev.txt"

def enable_by_file
FileUtils.mkdir_p("tmp")

if File.exist?(FILE)
delete_cache_file
puts "Development mode is no longer being cached."
else
create_cache_file
puts "Development mode is now being cached."
end

FileUtils.touch "tmp/restart.txt"
end
end
end
end

How Rails Uses the Caching File?

When your Rails application starts, it checks for the presence of the caching file above, and if it exists, it does the following:

  1. Enable perform_caching and enable_fragment_cache_logging on the controller.
  2. Set the cache store to :memory_store.
  3. Add the Cache-Control header to public with max-age set to two days.

Otherwise, it disables caching and uses the :null_store.

# config/environments/development.rb

if Rails.root.join("tmp/caching-dev.txt").exist?
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true

config.cache_store = :memory_store
config.public_file_server.headers = {
"Cache-Control" => "public, max-age=#{2.days.to_i}"
}
else
config.action_controller.perform_caching = false

config.cache_store = :null_store
end
  • perform_caching configures whether the application should perform the caching features provided by Action Controller or not.
  • enable_fragment_cache_logging determines whether to log fragment cache reads and writes in a verbose format.
  • cache_store configures which cache store to use for Rails caching.

The above settings instruct Rails to perform caching. How it implements it, well, that's a topic for another blog post. Stay tuned.

💡 This post is part of the Rails Internals series that explores the internals of Ruby on Rails by reading the source code.

Subscribe to get future posts via email (or grab the RSS feed)

Comments

No comments yet. Be the first to leave one.

Sign in to leave a comment.