`Rails.cache.clear` で FileStore のキャッシュが削除されなかった話
Published: 2021/9/11
問題
capistrano でのデプロイの度に、 Rails.cache.clear
を実行していたのだけれども、ActiveSupport::Cache::FileStore
のファイルが
削除されていないことがあったりしたので、その原因を調査した際の備忘録。
原因
def clear(options = nil)
root_dirs = (Dir.children(cache_path) - GITKEEP_FILES)
FileUtils.rm_r(root_dirs.collect { |f| File.join(cache_path, f) })
rescue Errno::ENOENT, Errno::ENOTEMPTY
end
出典:
rails/file_store.rb at f1a684ce9964f335072a3b2e8cb0b483e16056cb · rails/rails
Ruby on Rails. Contribute to rails/rails development by creating an account on GitHub.
github.com
ここにあるように、 ActiveSupport::Cache::FileStore
の .clear
メソッドは、 Errno::ENOENT
か Errno::ENOTEMPTY
の例外が発生した場合には、しれっとそれを握り潰して正常終了する。
さらには、この FileUtils.rm_r
のコマンドは、これを実行している最中にそのディレクトリの中にファイルを作成したりしていると、 Errono::ENOTEMPTY
が発生してしまう。
自分の場合だと、
- キャッシュディレクトリを linked_dir に指定
- デプロイ直後にキャッシュクリアを実行
していたため、 puma が新しいバージョンのアプリで起動しようとして、 bootsnap のキャッシュ(FileStore のデフォルトのキャッシュパスと同じ所tmp/cache
に生成される)をもりもり生成するタイミングと、Rails.cache.clear
のタイミングが被ってしまい、結果 Errono::ENOTEMPTY
が発生しそこでキャッシュの削除がアボートして正常終了する、という挙動になっていた。
対策
Rails.cache.clear
は、 puma の restart など、アプリの立ち上がり処理のタイミングを避けて実行する。
もしくは、キャッシュディレクトリは、デプロイの度に新しいものを用意するようにする。
サマリー FAQ
Q. FileStore の時、 Rails.cache.clear はどのように実行されますか?
Q. Rails.cache.clear とキャッシュ生成のタイミングが被るとどうなる?
Q. capistrano で cache clear を行う際に気をつける点は?
Tags: rails
関連記事
Rails の view では、相対パス(キー)のロケールが使える
2023/9/7
(Rails) Controller 等で helper を呼ぶ方法
2023/6/15
factory_bot と必須 association
2023/4/23
Rails とタイムゾーン
2023/4/19