Установка cache_store в инициализаторе
Я пытаюсь использовать redis-store как мой кеш-память Rails 3. У меня также есть initializer/app_config.rb, который загружает файл yaml для настроек конфигурации. В моем инициализаторе /redis.rb у меня есть:
MyApp::Application.config.cache_store = :redis_store, APP_CONFIG['redis']
Однако это не работает. Если я это сделаю:
Rails.cache
в консоли rails я могу видеть это с помощью
ActiveSupport.Cache.FileStore
в качестве хранилища кеша вместо redis-store. Однако, если я добавлю конфигурацию в свой файл application.rb следующим образом:
config.cache_store = :redis_store
он работает просто отлично, за исключением того, что инициализатор app config загружается после application.rb, поэтому у меня нет доступа к APP_CONFIG.
Кто-нибудь испытал это? Кажется, я не могу установить хранилище кеша в инициализаторе.
Ответы
Ответ 1
После some исследование, вероятным объяснением является то, что инициализатор 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
Ответ 2
Я пробовал следующее, и это работает.
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)
Ответ 3
В исходной настройке у вас было, помогает ли она:
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
?
Ответ 4
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://stackoverflow.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
Дополнительная информация
Ответ 5
Если бы одна и та же проблема и установка RAILS_CACHE
в MyApp::Application.config.cache_store
также исправила ее.
Ответ 6
В инициализаторе
REDIS ||= Rails.configuration.redis_client
В application.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 }