diff options
Diffstat (limited to 'activesupport/lib/active_support/cache')
5 files changed, 75 insertions, 64 deletions
diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index 5cd6065077..8ed60aebac 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -22,15 +22,15 @@ module ActiveSupport extend Strategy::LocalCache end - # Deletes all items from the cache. In this case it deletes all the entries in the specified - # file store directory except for .gitkeep. Be careful which directory is specified in your + # Deletes all items from the cache. In this case it deletes all the entries in the specified + # file store directory except for .gitkeep. Be careful which directory is specified in your # config file when using +FileStore+ because everything in that directory will be deleted. def clear(options = nil) root_dirs = Dir.entries(cache_path).reject {|f| (EXCLUDED_DIRS + [".gitkeep"]).include?(f)} FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)}) end - # Premptively iterates through all stored keys and removes the ones which have expired. + # Preemptively iterates through all stored keys and removes the ones which have expired. def cleanup(options = nil) options = merged_options(options) search_dir(cache_path) do |fname| @@ -43,33 +43,13 @@ module ActiveSupport # Increments an already existing integer value that is stored in the cache. # If the key is not found nothing is done. def increment(name, amount = 1, options = nil) - file_name = key_file_path(namespaced_key(name, options)) - lock_file(file_name) do - options = merged_options(options) - if num = read(name, options) - num = num.to_i + amount - write(name, num, options) - num - else - nil - end - end + modify_value(name, amount, options) end # Decrements an already existing integer value that is stored in the cache. # If the key is not found nothing is done. def decrement(name, amount = 1, options = nil) - file_name = key_file_path(namespaced_key(name, options)) - lock_file(file_name) do - options = merged_options(options) - if num = read(name, options) - num = num.to_i - amount - write(name, num, options) - num - else - nil - end - end + modify_value(name, -amount, options) end def delete_matched(matcher, options = nil) @@ -184,6 +164,22 @@ module ActiveSupport end end end + + # Modifies the amount of an already existing integer value that is stored in the cache. + # If the key is not found nothing is done. + def modify_value(name, amount, options) + file_name = key_file_path(namespaced_key(name, options)) + + lock_file(file_name) do + options = merged_options(options) + + if num = read(name, options) + num = num.to_i + amount + write(name, num, options) + num + end + end + end end end end diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index 512296554f..61b4f0b8b0 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -41,17 +41,15 @@ module ActiveSupport # # If no addresses are specified, then MemCacheStore will connect to # localhost port 11211 (the default memcached port). - # - # Instead of addresses one can pass in a MemCache-like object. For example: - # - # require 'memcached' # gem install memcached; uses C bindings to libmemcached - # ActiveSupport::Cache::MemCacheStore.new(Memcached::Rails.new("localhost:11211")) def initialize(*addresses) addresses = addresses.flatten options = addresses.extract_options! super(options) - if addresses.first.respond_to?(:get) + unless [String, Dalli::Client, NilClass].include?(addresses.first.class) + raise ArgumentError, "First argument must be an empty array, an array of hosts or a Dalli::Client instance." + end + if addresses.first.is_a?(Dalli::Client) @data = addresses.first else mem_cache_options = options.dup @@ -87,7 +85,7 @@ module ActiveSupport instrument(:increment, name, :amount => amount) do @data.incr(escape_key(namespaced_key(name, options)), amount) end - rescue Dalli::DalliError + rescue Dalli::DalliError => e logger.error("DalliError (#{e}): #{e.message}") if logger nil end @@ -101,7 +99,7 @@ module ActiveSupport instrument(:decrement, name, :amount => amount) do @data.decr(escape_key(namespaced_key(name, options)), amount) end - rescue Dalli::DalliError + rescue Dalli::DalliError => e logger.error("DalliError (#{e}): #{e.message}") if logger nil end diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb index 34ac91334a..8a0523d0e2 100644 --- a/activesupport/lib/active_support/cache/memory_store.rb +++ b/activesupport/lib/active_support/cache/memory_store.rb @@ -36,7 +36,7 @@ module ActiveSupport end end - # Premptively iterates through all stored keys and removes the ones which have expired. + # Preemptively iterates through all stored keys and removes the ones which have expired. def cleanup(options = nil) options = merged_options(options) instrument(:cleanup, :size => @data.size) do diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb index cea7eee924..73c6b3cb88 100644 --- a/activesupport/lib/active_support/cache/strategy/local_cache.rb +++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/object/duplicable' require 'active_support/core_ext/string/inflections' +require 'active_support/per_thread_registry' module ActiveSupport module Cache @@ -8,6 +9,8 @@ module ActiveSupport # duration of a block. Repeated calls to the cache for the same key will hit the # in-memory cache for faster access. module LocalCache + autoload :Middleware, 'active_support/cache/strategy/local_cache_middleware' + # Class for storing and registering the local caches. class LocalCacheRegistry # :nodoc: extend ActiveSupport::PerThreadRegistry @@ -63,32 +66,6 @@ module ActiveSupport def with_local_cache use_temporary_local_cache(LocalStore.new) { yield } end - - #-- - # This class wraps up local storage for middlewares. Only the middleware method should - # construct them. - class Middleware # :nodoc: - attr_reader :name, :local_cache_key - - def initialize(name, local_cache_key) - @name = name - @local_cache_key = local_cache_key - @app = nil - end - - def new(app) - @app = app - self - end - - def call(env) - LocalCacheRegistry.set_cache_for(local_cache_key, LocalStore.new) - @app.call(env) - ensure - LocalCacheRegistry.set_cache_for(local_cache_key, nil) - end - end - # Middleware class can be inserted as a Rack handler to be local cache for the # duration of request. def middleware @@ -109,13 +86,13 @@ module ActiveSupport def increment(name, amount = 1, options = nil) # :nodoc: value = bypass_local_cache{super} - increment_or_decrement(value, name, amount, options) + set_cache_value(value, name, amount, options) value end def decrement(name, amount = 1, options = nil) # :nodoc: value = bypass_local_cache{super} - increment_or_decrement(value, name, amount, options) + set_cache_value(value, name, amount, options) value end @@ -143,8 +120,7 @@ module ActiveSupport super end - private - def increment_or_decrement(value, name, amount, options) + def set_cache_value(value, name, amount, options) if local_cache local_cache.mute do if value @@ -156,6 +132,8 @@ module ActiveSupport end end + private + def local_cache_key @local_cache_key ||= "#{self.class.name.underscore}_local_cache_#{object_id}".gsub(/[\/-]/, '_').to_sym end diff --git a/activesupport/lib/active_support/cache/strategy/local_cache_middleware.rb b/activesupport/lib/active_support/cache/strategy/local_cache_middleware.rb new file mode 100644 index 0000000000..901c2e05a8 --- /dev/null +++ b/activesupport/lib/active_support/cache/strategy/local_cache_middleware.rb @@ -0,0 +1,39 @@ +require 'rack/body_proxy' +module ActiveSupport + module Cache + module Strategy + module LocalCache + + #-- + # This class wraps up local storage for middlewares. Only the middleware method should + # construct them. + class Middleware # :nodoc: + attr_reader :name, :local_cache_key + + def initialize(name, local_cache_key) + @name = name + @local_cache_key = local_cache_key + @app = nil + end + + def new(app) + @app = app + self + end + + def call(env) + LocalCacheRegistry.set_cache_for(local_cache_key, LocalStore.new) + response = @app.call(env) + response[2] = ::Rack::BodyProxy.new(response[2]) do + LocalCacheRegistry.set_cache_for(local_cache_key, nil) + end + response + rescue Exception + LocalCacheRegistry.set_cache_for(local_cache_key, nil) + raise + end + end + end + end + end +end |