こんにちは、hachi8833です。BigBinaryシリーズ、今回はRails 5でdevelopmentモードのキャッシュを簡単にオンオフできる機能を紹介します。
元記事
確認に使った環境
- Railsバージョン: 5.0.2(5.0-stable)
- Rubyバージョン: 2.4.0p0
Rails 5の新機能: developmentモードのキャッシュを簡単に制御できるようになった
Rails 4まで
Rails 4までは、developmentモードのキャッシュを切り替えるためにいちいちconfig/environments/development.rbを開いて以下の設定のfalse/trueを切り替え、さらにサーバーを再起動しなくてはなりませんでした。
config.action_controller.perform_caching = false
ローカルキャッシュの動作を調べたりするときに地味に面倒です。
Rails 5以降
Rails 5では、developmentモードのキャッシュを簡単に作成できる新しいコマンドが導入されました。これにより、キャッシュの動作を切り替えて振る舞いの違いを簡単に確認できます。DHHの要請で追加された機能です。
- Issue: #18875: rake dev:cache
- Pull Request: #20961: Add dev caching toggle / server options
訳注: Rails 5.0.2のconfig.action_controller.perform_caching
のデフォルト設定は以下のとおりです。
- development:
false
(tmp/caching-dev.txtがある場合のみtrue
) - production:
true
- test:
false
$ rails dev:cache
Development mode is now being cached.
上のようにrails dev:cache
コマンドを実行すると、tmp/ディレクトリにcaching-dev.txtファイルが作成されます。
キャッシュの仕組み
Rails 5で新規作成したRailsアプリでは、config/environments/development.rbに以下のコードが含まれるようになりました。以下は5.0.2で確認しました。
# Enable/disable caching. By default caching is disabled.
if Rails.root.join('tmp/caching-dev.txt').exist?
config.action_controller.perform_caching = true
config.cache_store = :memory_store
config.public_file_server.headers = {
'Cache-Control' => 'public, max-age=172800'
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
このコードでは、tmp/caching-dev.txtが存在する場合にのみ:mem_cache_store
でキャッシュを有効にします。
以下は当時のdev_cacheコマンドのソースです。
def dev_cache
if File.exist? 'tmp/caching-dev.txt'
File.delete 'tmp/caching-dev.txt'
puts 'Development mode is no longer being cached.'
else
FileUtils.touch 'tmp/caching-dev.txt'
puts 'Development mode is now being cached.'
end
FileUtils.touch 'tmp/restart.txt'
end
訳注: ただしその後コードがさらに変わり、現在はモジュールとしてrailties/lib/rails/dev_caching.rbにあります。
require "fileutils"
module Rails
module DevCaching # :nodoc:
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"
FileUtils.rm_f("tmp/pids/server.pid")
end
def enable_by_argument(caching)
FileUtils.mkdir_p("tmp")
if caching
create_cache_file
elsif caching == false && File.exist?(FILE)
delete_cache_file
end
end
private
def create_cache_file
FileUtils.touch FILE
end
def delete_cache_file
File.delete FILE
end
end
end
end
新機能のメリットと注意
キャッシュのオン/オフを切り替えるためにサーバーを再起動する必要がなくなりました。dev:cache
コマンドを実行したときに内部で実行されるdev_cache
がよしなにやってくれます。tmp/restart.txtがtouch
で作成されることをソースコードで確認できます。
この機能はunicorn、thin、webrickではサポートされないのでご注意ください。この点について、DHHのチームではpowを採用しており、powはtmp/restart.txtをtouch
すると再起動するようになっているからではないかと(元記事の著者が)推測しています。実際、DHHはだいぶ以前にもspringの監視リストにtmp/restart.txtを追加するissueを作成しています。
キャッシュをオフにするには
rails dev:cache
コマンドはトグルになっているので、実行のたびにオンとオフが切り替わります。
$ rails dev:cache
Development mode is no longer being cached.
訳注
Pumaについて
原文ではRails 5のデフォルトのサーバーであるPumaについて言及がありません。Rails 5.0.2の素の環境で試してみたところ、少なくとも設定レベルではPumaで正常に動作していることを確認できました。
ビューで<%= Rails.cache %>
と<%= Rails.configuration.cache_store %>
を追加しただけの簡素な方法です。
rails dev:cache
でオンにした場合
rails dev:cache
でオフにした場合
rails dev:cache
を実行するとRailsが再起動されるので、2、3秒待つ必要があります。
Railsの起動オプションでdevelopmentキャッシュを指定する
デフォルトではdevelopmentキャッシュはオフになります。
rails start
に--no-dev-caching
を付けると、developmentキャッシュを明示的にオフにして起動できます。
rails start
に--dev-caching
を付けると、developmentキャッシュを明示的にオンにして起動できます。
不要な場合はdevelopmentキャッシュをオンにしないようにしましょう。