support redis as well as memcache for a rails cache store

closes #4498

Change-Id: Icf29882d8c0d351574496ba0494c1d8c518a3e7f
Reviewed-on: https://gerrit.instructure.com/4580
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Zach Wily <zach@instructure.com>
This commit is contained in:
Brian Palmer 2011-07-06 15:43:19 -06:00
parent e295e45ae5
commit 630200c32e
9 changed files with 98 additions and 10 deletions

View File

@ -75,7 +75,7 @@ group :development do
end
group :redis do
gem 'redis-store', '1.0.0.beta4'
gem 'redis-store', '1.0.0.rc1'
end
# The closure-compiler gem has an undocumented

View File

@ -0,0 +1,13 @@
# if this file doesn't exist, memcache will be used if there are any
# servers configured in config/memcache.yml
development:
cache_store: mem_cache_store
# if no servers are specified, we'll look in config/memcache.yml
# servers:
# - localhost
#
# cache_store: redis_store
# # if no servers are specified, we'll look in config/redis.yml
# servers:
# - localhost
# database: 0

View File

@ -35,13 +35,6 @@ Rails::Initializer.run do |config|
# Run "rake -D time" for a list of tasks for finding time zone names. Comment line to use default local time.
config.time_zone = 'UTC'
memcache_servers = File.exists?(Rails.root+"config/memcache.yml") ? (YAML.load_file(Rails.root+"config/memcache.yml")[RAILS_ENV] || []) : []
if memcache_servers.empty?
config.cache_store = :nil_store
else
config.cache_store = :mem_cache_store, *memcache_servers
end
log_config = File.exists?(Rails.root+"config/logging.yml") && YAML.load_file(Rails.root+"config/logging.yml")[RAILS_ENV]
if log_config && log_config["logger"] == "syslog"
require 'syslog_wrapper'

View File

@ -30,5 +30,11 @@ end
# eval <env>-local.rb if it exists
Dir[File.dirname(__FILE__) + "/" + File.basename(__FILE__, ".rb") + "-*.rb"].each { |localfile| eval(File.new(localfile).read) }
# initialize cache store
# this needs to happen in each environment config file, rather than a
# config/initializer/* file, to allow Rails' full initialization of the cache
# to take place, including middleware inserts and such.
config.cache_store = Canvas.cache_store_config
# allow debugging only in development environment by default
require "ruby-debug"

View File

@ -17,3 +17,9 @@ config.action_view.cache_template_loading = true
# eval <env>-local.rb if it exists
Dir[File.dirname(__FILE__) + "/" + File.basename(__FILE__, ".rb") + "-*.rb"].each { |localfile| eval(File.new(localfile).read) }
# initialize cache store
# this needs to happen in each environment config file, rather than a
# config/initializer/* file, to allow Rails' full initialization of the cache
# to take place, including middleware inserts and such.
config.cache_store = Canvas.cache_store_config

View File

@ -32,3 +32,5 @@ Canvas.dynamic_finder_type_cast_error = :raise
# eval <env>-local.rb if it exists
Dir[File.dirname(__FILE__) + "/" + File.basename(__FILE__, ".rb") + "-*.rb"].each { |localfile| eval(File.new(localfile).read) }
config.cache_store = :nil_store

View File

@ -1,5 +1,4 @@
# if an environment has no servers defined, we'll use NilStore instead, which
# effectively disables caching
# see also config/cache_store.yml.example
production:
development:

View File

@ -47,6 +47,32 @@ module Canvas
@redis_enabled ||= Setting.from_config('redis').present?
end
def self.cache_store_config
cache_store_config = {
'cache_store' => 'mem_cache_store',
}.merge(Setting.from_config('cache_store') || {})
config = nil
case cache_store_config.delete('cache_store')
when 'mem_cache_store'
cache_store_config['namespace'] ||= cache_store_config['key']
servers = cache_store_config['servers'] || (Setting.from_config('memcache'))
if servers
config = :mem_cache_store, servers, cache_store_config
end
when 'redis_store'
Bundler.require 'redis'
Canvas::Redis.patch
# merge in redis.yml, but give precedence to cache_store.yml
cache_store_config = (Setting.from_config('redis') || {}).merge(cache_store_config)
cache_store_config['key_prefix'] ||= cache_store_config['key']
config = :redis_store, cache_store_config
end
unless config
config = :nil_store
end
config
end
# `sample` reports KB, not B
if File.directory?("/proc")
# linux w/ proc fs

43
lib/canvas/redis.rb Normal file
View File

@ -0,0 +1,43 @@
module Canvas::Redis
# while we wait for this pull request
# https://github.com/jodosha/redis-store/pull/83
def self.patch
::ActiveSupport::Cache::RedisStore.class_eval do
def write_with_econnrefused(key, value, options = nil)
write_without_econnrefused(key, value, options)
rescue Errno::ECONNREFUSED => e
false
end
alias_method_chain :write, :econnrefused
def read_with_econnrefused(key, options = nil)
read_without_econnrefused(key, options)
rescue Errno::ECONNREFUSED => e
nil
end
alias_method_chain :read, :econnrefused
def delete_with_econnrefused(key, options = nil)
delete_without_econnrefused(key, options)
rescue Errno::ECONNREFUSED => e
false
end
alias_method_chain :delete, :econnrefused
def exist_with_econnrefused?(key, options = nil)
exist_without_econnrefused?(key, options = nil)
rescue Errno::ECONNREFUSED => e
false
end
alias_method_chain :exist?, :econnrefused
def delete_matched_with_econnrefused(matcher, options = nil)
delete_matched_without_econnrefused(matcher, options)
rescue Errno::ECONNREFUSED => e
false
end
alias_method_chain :delete_matched, :econnrefused
end
end
end