Class: ActiveSupport::Cache::MemCacheStore

Inherits:
Store show all
Defined in:
activesupport/lib/active_support/cache/mem_cache_store.rb

Overview

A cache store implementation which stores data in Memcached: memcached.org

This is currently the most popular cache store for production websites.

Special features:

  • Clustering and load balancing. One can specify multiple memcached servers, and MemCacheStore will load balance between all available servers. If a server goes down, then MemCacheStore will ignore it until it comes back up.

MemCacheStore implements the Strategy::LocalCache strategy which implements an in-memory cache inside of a block.

Defined Under Namespace

Modules: Coders, DupLocalCache

Constant Summary collapse

OVERRIDDEN_OPTIONS =

These options represent behavior overridden by this implementation and should not be allowed to get down to the Dalli client

UNIVERSAL_OPTIONS
KEY_MAX_SIZE =
250
ESCAPE_KEY_CHARS =
/[\x00-\x20%\x7F-\xFF]/n

Instance Attribute Summary

Attributes inherited from Store

#options, #silence

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Store

#cleanup, #delete, #delete_matched, #delete_multi, #exist?, #fetch, #fetch_multi, #mute, #new_entry, #read, #read_multi, #silence!, #write, #write_multi

Constructor Details

#initialize(*addresses) ⇒ MemCacheStore

Creates a new MemCacheStore object, with the given memcached server addresses. Each address is either a host name, or a host-with-port string in the form of “host_name:port”. For example:

ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229")

If no addresses are provided, but ENV['MEMCACHE_SERVERS'] is defined, it will be used instead. Otherwise, MemCacheStore will connect to localhost:11211 (the default memcached port). Passing a Dalli::Client instance is deprecated and will be removed. Please pass an address instead.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'activesupport/lib/active_support/cache/mem_cache_store.rb', line 116

def initialize(*addresses)
  addresses = addresses.flatten
  options = addresses.extract_options!
  if options.key?(:cache_nils)
    options[:skip_nil] = !options.delete(:cache_nils)
  end
  super(options)

  unless [String, Dalli::Client, NilClass].include?(addresses.first.class)
    raise ArgumentError, "First argument must be an empty array, address, or array of addresses."
  end
  if addresses.first.is_a?(Dalli::Client)
    ActiveSupport.deprecator.warn(<<~MSG)
      Initializing MemCacheStore with a Dalli::Client is deprecated and will be removed in Rails 7.2.
      Use memcached server addresses instead.
    MSG
    @data = addresses.first
  else
    mem_cache_options = options.dup
    # The value "compress: false" prevents duplicate compression within Dalli.
    mem_cache_options[:compress] = false
    (OVERRIDDEN_OPTIONS - %i(compress)).each { |name| mem_cache_options.delete(name) }
    @data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))
  end
end

Class Method Details

.build_mem_cache(*addresses) ⇒ Object

Creates a new Dalli::Client instance with specified addresses and options. If no addresses are provided, we give nil to Dalli::Client, so it uses its fallbacks:

  • ENV (if defined)

  • “127.0.0.1:11211” (otherwise)

    ActiveSupport::Cache::MemCacheStore.build_mem_cache

    # => #<Dalli::Client:0x007f98a47d2028 @servers=["127.0.0.1:11211"], @options={}, @ring=nil>
    

    ActiveSupport::Cache::MemCacheStore.build_mem_cache(‘localhost:10290’)

    # => #<Dalli::Client:0x007f98a47b3a60 @servers=["localhost:10290"], @options={}, @ring=nil>
    


94
95
96
97
98
99
100
101
102
103
104
105
# File 'activesupport/lib/active_support/cache/mem_cache_store.rb', line 94

def self.build_mem_cache(*addresses) # :nodoc:
  addresses = addresses.flatten
  options = addresses.extract_options!
  addresses = nil if addresses.compact.empty?
  pool_options = retrieve_pool_options(options)

  if pool_options.empty?
    Dalli::Client.new(addresses, options)
  else
    ConnectionPool.new(pool_options) { Dalli::Client.new(addresses, options.merge(threadsafe: false)) }
  end
end

.supports_cache_versioning?Boolean

Advertise cache versioning support.

Returns:

  • (Boolean)


36
37
38
# File 'activesupport/lib/active_support/cache/mem_cache_store.rb', line 36

def self.supports_cache_versioning?
  true
end

Instance Method Details

#clear(options = nil) ⇒ Object

Clear the entire cache on all memcached servers. This method should be used with care when shared cache is being used.



208
209
210
# File 'activesupport/lib/active_support/cache/mem_cache_store.rb', line 208

def clear(options = nil)
  rescue_error_with(nil) { @data.with { |c| c.flush_all } }
end

#decrement(name, amount = 1, options = nil) ⇒ Object

Decrement a cached integer value using the memcached decr atomic operator. Returns the updated value.

If the key is unset or has expired, it will be set to 0. Memcached does not support negative counters.

cache.decrement("foo") # => 0

To set a specific value, call #write passing raw: true:

cache.write("baz", 5, raw: true)
cache.decrement("baz") # => 4

Decrementing a non-numeric value, or a value written without raw: true, will fail and return nil.



197
198
199
200
201
202
203
204
# File 'activesupport/lib/active_support/cache/mem_cache_store.rb', line 197

def decrement(name, amount = 1, options = nil)
  options = merged_options(options)
  instrument(:decrement, name, amount: amount) do
    rescue_error_with nil do
      @data.with { |c| c.decr(normalize_key(name, options), amount, options[:expires_in], 0) }
    end
  end
end

#increment(name, amount = 1, options = nil) ⇒ Object

Increment a cached integer value using the memcached incr atomic operator. Returns the updated value.

If the key is unset or has expired, it will be set to amount:

cache.increment("foo") # => 1
cache.increment("bar", 100) # => 100

To set a specific value, call #write passing raw: true:

cache.write("baz", 5, raw: true)
cache.increment("baz") # => 6

Incrementing a non-numeric value, or a value written without raw: true, will fail and return nil.



173
174
175
176
177
178
179
180
# File 'activesupport/lib/active_support/cache/mem_cache_store.rb', line 173

def increment(name, amount = 1, options = nil)
  options = merged_options(options)
  instrument(:increment, name, amount: amount) do
    rescue_error_with nil do
      @data.with { |c| c.incr(normalize_key(name, options), amount, options[:expires_in], amount) }
    end
  end
end

#statsObject

Get the statistics from the memcached servers.



213
214
215
# File 'activesupport/lib/active_support/cache/mem_cache_store.rb', line 213

def stats
  @data.with { |c| c.stats }
end