class ActiveSupport::Cache::MemcachedStore
A cache store implementation which stores data in Memcached: memcached.org/
MemcachedStore
uses memcached gem as backend to connect to Memcached server.
MemcachedStore
implements the Strategy::LocalCache strategy which implements an in-memory cache inside of a block.
Constants
- ESCAPE_KEY_CHARS
Attributes
read_only[RW]
swallow_exceptions[RW]
Public Class Methods
new(*addresses, **options)
click to toggle source
Calls superclass method
# File lib/active_support/cache/memcached_store.rb, line 64 def initialize(*addresses, **options) addresses = addresses.flatten options[:codec] ||= Codec.new @swallow_exceptions = true @swallow_exceptions = options.delete(:swallow_exceptions) if options.key?(:swallow_exceptions) super(options) if addresses.first.is_a?(Memcached) @connection = addresses.first raise "Memcached::Rails is no longer supported, "\ "use a Memcached instance instead" if @connection.is_a?(Memcached::Rails) else mem_cache_options = options.dup servers = mem_cache_options.delete(:servers) UNIVERSAL_OPTIONS.each { |name| mem_cache_options.delete(name) } @connection = Memcached.new([*addresses, *servers], mem_cache_options) end end
Public Instance Methods
append(name, value, options = nil)
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 84 def append(name, value, options = nil) return true if read_only options = merged_options(options) normalized_key = normalize_key(name, options) handle_exceptions(return_value_on_error: nil, on_miss: false, miss_exceptions: [Memcached::NotStored]) do instrument(:append, name) do @connection.append(normalized_key, value) end true end end
cas(name, options = nil) { |value| ... }
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 128 def cas(name, options = nil) options = merged_options(options) key = normalize_key(name, options) handle_exceptions(return_value_on_error: false) do instrument(:cas, name, options) do @connection.cas(key, expiration(options)) do |raw_value| entry = deserialize_entry(raw_value) value = yield entry.value break true if read_only serialize_entry(Entry.new(value, **options), options) end end true end end
cas_multi(*names, **options) { |values| ... }
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 145 def cas_multi(*names, **options) return if names.empty? options = merged_options(options) keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }] handle_exceptions(return_value_on_error: false) do instrument(:cas_multi, names, options) do @connection.cas(keys_to_names.keys, expiration(options)) do |raw_values| values = {} raw_values.each do |key, raw_value| entry = deserialize_entry(raw_value) values[keys_to_names[key]] = entry.value unless entry.expired? end values = yield values break true if read_only serialized_values = values.map do |name, value| [normalize_key(name, options), serialize_entry(Entry.new(value, **options), options)] end Hash[serialized_values] end true end end end
clear(options = nil)
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 194 def clear(options = nil) ActiveSupport::Notifications.instrument("cache_clear.active_support", options || {}) do @connection.flush end end
delete(*)
click to toggle source
Calls superclass method
# File lib/active_support/cache/memcached_store.rb, line 102 def delete(*) return true if read_only super end
exist?(*)
click to toggle source
Calls superclass method
# File lib/active_support/cache/memcached_store.rb, line 206 def exist?(*) !!super end
read_multi(*names)
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 107 def read_multi(*names) options = names.extract_options! return {} if names.empty? options = merged_options(options) keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }] values = {} handle_exceptions(return_value_on_error: {}) do instrument(:read_multi, names, options) do if raw_values = @connection.get(keys_to_names.keys) raw_values.each do |key, value| entry = deserialize_entry(value) values[keys_to_names[key]] = entry.value unless entry.expired? end end end values end end
stats()
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 200 def stats ActiveSupport::Notifications.instrument("cache_stats.active_support") do @connection.stats end end
write(*)
click to toggle source
Calls superclass method
# File lib/active_support/cache/memcached_store.rb, line 97 def write(*) return true if read_only super end
Private Instance Methods
deserialize_entry(value)
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 319 def deserialize_entry(value) unless value.nil? value.is_a?(Entry) ? value : Entry.new(value, compress: false) end end
expiration(options)
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 333 def expiration(options) expires_in = options[:expires_in].to_i if expires_in > 0 && options[:race_condition_ttl] && !options[:raw] expires_in += options[:race_condition_ttl].to_i end expires_in end
handle_exceptions(return_value_on_error:, on_miss: return_value_on_error, miss_exceptions: []) { || ... }
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 341 def handle_exceptions(return_value_on_error:, on_miss: return_value_on_error, miss_exceptions: []) yield rescue Memcached::NotFound, Memcached::ConnectionDataExists, *miss_exceptions on_miss rescue Memcached::Error => e log_warning(e) raise unless @swallow_exceptions return_value_on_error end
log_warning(err)
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 351 def log_warning(err) return unless logger return if err.is_a?(Memcached::NotStored) && @swallow_exceptions logger.warn( "[MEMCACHED_ERROR] swallowed=#{@swallow_exceptions}" \ " exception_class=#{err.class} exception_message=#{err.message}" ) end
normalize_key(key, options)
click to toggle source
Calls superclass method
# File lib/active_support/cache/memcached_store.rb, line 310 def normalize_key(key, options) key = super.dup key = key.force_encoding(Encoding::ASCII_8BIT) key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" } # When we remove support to Rails 5.1 we can change the code to use ActiveSupport::Digest key = "#{key[0, 213]}:md5:#{::Digest::MD5.hexdigest(key)}" if key.size > 250 key end
read_serialized_entry(key, **)
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 261 def read_serialized_entry(key, **) handle_exceptions(return_value_on_error: nil) do @connection.get(key) end end
serialize_entry(entry, options)
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 325 def serialize_entry(entry, options) if options[:raw] entry.value.to_s else entry end end
write_serialized_entry(key, value, **options)
click to toggle source
# File lib/active_support/cache/memcached_store.rb, line 273 def write_serialized_entry(key, value, **options) method = options && options[:unless_exist] ? :add : :set expires_in = expiration(options) handle_exceptions(return_value_on_error: false) do @connection.send(method, key, value, expires_in) true end end