Установка 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

Дальнейшая информация

Я попробовал следующее, и это работает.

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 }
Другие вопросы по тегам