Class: ActiveSupport::Cache::DalliStore

Inherits:
Store
  • Object
show all
Defined in:
lib/active_support/cache/dalli_store.rb,
lib/active_support/cache/dalli_store23.rb

Overview

A cache store implementation which stores data in Memcached: www.danga.com/memcached/

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

Defined Under Namespace

Modules: LocalCacheWithRaw

Constant Summary collapse

ESCAPE_KEY_CHARS =
/[\x00-\x20%\x7F-\xFF]/
RAW =
{ :raw => true }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*addresses) ⇒ DalliStore

Creates a new DalliStore 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::DalliStore.new("localhost", "server-downstairs.localnetwork:8229")

If no addresses are specified, then DalliStore will connect to localhost port 11211 (the default memcached port).



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/active_support/cache/dalli_store.rb', line 38

def initialize(*addresses)
  addresses = addresses.flatten
  options = addresses.extract_options!
  super(options)

  mem_cache_options = options.dup
  UNIVERSAL_OPTIONS.each{|name| mem_cache_options.delete(name)}
  @data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))

  extend Strategy::LocalCache
  extend LocalCacheWithRaw
end

Class Method Details

.build_mem_cache(*addresses) ⇒ Object



22
23
24
25
26
27
# File 'lib/active_support/cache/dalli_store.rb', line 22

def self.build_mem_cache(*addresses)
  addresses = addresses.flatten
  options = addresses.extract_options!
  addresses = ["localhost:11211"] if addresses.empty?
  Dalli::Client.new(addresses, options)
end

Instance Method Details

#clearObject

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



102
103
104
# File 'lib/active_support/cache/dalli_store.rb', line 102

def clear(options = nil)
  @data.flush_all
end

#decrement(key, amount = 1) ⇒ Object

Decrement a cached value. This method uses the memcached decr atomic operator and can only be used on values written with the :raw option. Calling it on a value not stored with :raw will initialize that value to zero.



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/active_support/cache/dalli_store.rb', line 88

def decrement(name, amount = 1, options = nil) # :nodoc:
  options = merged_options(options)
  initial = options[:initial] || 0
  expires_in = options[:expires_in].to_i
  response = instrument(:decrement, name, :amount => amount) do
    @data.decr(escape_key(namespaced_key(name, options)), amount, expires_in, initial)
  end
rescue Dalli::DalliError => e
  logger.error("DalliError: #{e.message}") if logger
  nil
end

#delete(key, options = nil) ⇒ Object

:nodoc:



97
98
99
100
101
102
103
# File 'lib/active_support/cache/dalli_store23.rb', line 97

def delete(key, options = nil) # :nodoc:
  super
  @data.delete(escape_key(key))
rescue Dalli::DalliError => e
  logger.error("DalliError: #{e.message}")
  false
end

#delete_matched(matcher, options = nil) ⇒ Object

:nodoc:



136
137
138
139
140
141
# File 'lib/active_support/cache/dalli_store23.rb', line 136

def delete_matched(matcher, options = nil) # :nodoc:
  # don't do any local caching at present, just pass
  # through and let the error happen
  super
  raise "Not supported by Memcache"
end

#exist?(key, options = nil) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


105
106
107
108
109
110
# File 'lib/active_support/cache/dalli_store23.rb', line 105

def exist?(key, options = nil) # :nodoc:
  # Doesn't call super, cause exist? in memcache is in fact a read
  # But who cares? Reading is very fast anyway
  # Local cache is checked first, if it doesn't know then memcache itself is read from
  !read(key, options).nil?
end

#increment(key, amount = 1) ⇒ Object

Increment a cached value. This method uses the memcached incr atomic operator and can only be used on values written with the :raw option. Calling it on a value not stored with :raw will initialize that value to zero.



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/active_support/cache/dalli_store.rb', line 71

def increment(name, amount = 1, options = nil) # :nodoc:
  options = merged_options(options)
  initial = options[:initial] || amount
  expires_in = options[:expires_in].to_i
  response = instrument(:increment, name, :amount => amount) do
    @data.incr(escape_key(namespaced_key(name, options)), amount, expires_in, initial)
  end
rescue Dalli::DalliError => e
  logger.error("DalliError: #{e.message}") if logger
  nil
end

#read(key, options = nil) ⇒ Object

Read an entry from the cache.



72
73
74
75
76
77
78
# File 'lib/active_support/cache/dalli_store23.rb', line 72

def read(key, options = nil) # :nodoc:
  super
  @data.get(escape_key(key), options)
rescue Dalli::DalliError => e
  logger.error("DalliError: #{e.message}")
  nil
end

#read_multi(*names) ⇒ Object

Reads multiple keys from the cache using a single call to the servers for all keys. Options can be passed in the last argument.



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/active_support/cache/dalli_store.rb', line 53

def read_multi(*names)
  options = names.extract_options!
  options = merged_options(options)
  keys_to_names = names.inject({}){|map, name| map[escape_key(namespaced_key(name, options))] = name; map}
  raw_values = @data.get_multi(keys_to_names.keys, RAW)
  values = {}
  raw_values.each do |key, value|
    entry = deserialize_entry(value)
    values[keys_to_names[key]] = entry.value unless entry.expired?
  end
  values
end

#resetObject



111
112
113
# File 'lib/active_support/cache/dalli_store.rb', line 111

def reset
  @data.reset
end

#statsObject

Get the statistics from the memcached servers.



107
108
109
# File 'lib/active_support/cache/dalli_store.rb', line 107

def stats
  @data.stats
end

#write(key, value, options = nil) ⇒ Object

Writes a value to the cache.

Possible options:

  • :unless_exist - set to true if you don’t want to update the cache if the key is already set.

  • :expires_in - the number of seconds that this value may stay in the cache. See ActiveSupport::Cache::Store#write for an example.



87
88
89
90
91
92
93
94
95
# File 'lib/active_support/cache/dalli_store23.rb', line 87

def write(key, value, options = nil)
  super
  value = value.to_s if options && options[:raw]
  method = options && options[:unless_exist] ? :add : :set
  @data.send(method, escape_key(key), value, expires_in(options), options)
rescue Dalli::DalliError => e
  logger.error("DalliError: #{e.message}")
  false
end