Установка cache_store в инициализаторе
Я пытаюсь использовать redis-store в качестве моего Rails 3 cache_store. У меня также есть инициализатор /app_config.rb, который загружает файл yaml для настроек конфигурации. В моем инициализаторе / redis.rb у меня есть:
MyApp::Application.config.cache_store = :redis_store, APP_CONFIG['redis']
Тем не менее, это не похоже на работу. Если я сделаю:
Rails.cache
в моей консоли рельсов я могу ясно видеть, что он использует
ActiveSupport.Cache.FileStore
в качестве хранилища кеша вместо redis-store. Тем не менее, если я добавлю конфиг в моем файле application.rb следующим образом:
config.cache_store = :redis_store
он работает просто отлично, за исключением того, что инициализатор конфигурации приложения загружается после application.rb, поэтому у меня нет доступа к APP_CONFIG.
Кто-нибудь испытывал это? Я не могу установить хранилище кэша в инициализаторе.
6 ответов
После некоторого исследования вероятное объяснение состоит в том, что инициализатор initialize_cache запускается раньше, чем рельсы / инициализаторы. Так что, если он не определен ранее в цепочке выполнения, хранилище кэша не будет установлено. Вы должны настроить его ранее в цепочке, как в application.rb или средах / production.rb
Моим решением было перенести загрузку APP_CONFIG до того, как приложение будет настроено так:
APP_CONFIG = YAML.load_file(File.expand_path('../config.yml', __FILE__))[Rails.env]
а затем в том же файле:
config.cache_store = :redis_store, APP_CONFIG['redis']
Другим вариантом было поместить cache_store в блок before_configuration, что-то вроде этого:
config.before_configuration do
APP_CONFIG = YAML.load_file(File.expand_path('../config.yml', __FILE__))[Rails.env]
config.cache_store = :redis_store, APP_CONFIG['redis']
end
config/initializers
запускаются после Rails.cache
инициализируется, но после config/application.rb
а также config/environments
,
Конфигурация в config / application.rb или окружении
Таким образом, одним из решений будет настройка кеша в config/application.rb
или же config/environments/*.rb
,
Конфигурация в config / initializers / cache.rb
Если кеш должен быть настроен в инициализаторе преднамеренно, это можно сделать, установив Rails.cache
вручную после настройки:
# config/initializers/cache.rb
Rails.application.config.cache_store = :redis_store, APP_CONFIG['redis']
# Make sure to add this line (http://stackru.com/a/38619281/2066546):
Rails.cache = ActiveSupport::Cache.lookup_store(Rails.application.config.cache_store)
Добавить спецификацию
Чтобы убедиться, что это работает, добавьте спецификацию, подобную этой:
# spec/features/smoke_spec.rb
require 'spec_helper'
feature "Smoke test" do
scenario "Testing the rails cache" do
Rails.cache.write "foo", "bar"
expect(Rails.cache.read("foo")).to eq "bar"
expect(Rails.cache).to be_kind_of ActiveSupport::Cache::RedisStore
end
end
Дальнейшая информация
Rails.cache
устанавливается здесь во время начальной загрузки приложения: https://github.com/rails/rails/blob/5-0-stable/railties/lib/rails/application/bootstrap.rb#L62L70. Магазин Redis не отвечает на:middleware
, Таким образом, мы можем опустить дополнительные строки.- Смотрите также: https://github.com/rails/rails/issues/10908
- http://guides.rubyonrails.org/caching_with_rails.html
Я попробовал следующее, и это работает.
MyApp::Application.config.cache_store = :redis_store
self.class.send :remove_const, :RAILS_CACHE if self.class.const_defined? :RAILS_CACHE
RAILS_CACHE = ActiveSupport::Cache.lookup_store(MyApp::Application.config.cache_store)
В исходной настройке это поможет, если вы измените:
MyApp::Application.config.cache_store = :redis_store, APP_CONFIG['redis']
чтобы:
MyApp::Application.config.cache_store = :redis_store, APP_CONFIG['redis']
RAILS_CACHE = MyApp::Application.config.cache_store
?
Была такая же проблема и настройки RAILS_CACHE
в MyApp::Application.config.cache_store
исправил это также.
В инициализаторе
REDIS ||= Rails.configuration.redis_client
В приложении.rb
config.redis_client = Redis.new({
:host => ENV["REDIS_HOST"],
:port => ENV["REDIS_PORT"],
:db => ENV["REDIS_DB"].to_i,
})
config.cache_store = :redis_store, { client: config.redis_client }