Class: MemCachedSupportStore

Inherits:
ActiveSupport::Cache::Store
  • Object
show all
Defined in:
lib/mem_cached_support_store.rb

Overview

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

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 goes back online.

  • Time-based expiry support. See #write and the :expires_in option.

  • Per-request in memory cache for all communication with the MemCache server(s).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*addresses) ⇒ MemCachedSupportStore

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 specified, then MemCacheStore will connect to localhost port 11211 (the default memcached port).



27
28
29
30
31
32
33
34
35
36
# File 'lib/mem_cached_support_store.rb', line 27

def initialize(*addresses)
  addresses = addresses.flatten
  options = addresses.extract_options!
  options[:prefix_key] ||= options[:namespace]
  addresses = ["localhost"] if addresses.empty?
  @addresses = addresses
  @data = Memcached.new(addresses, options)

  extend ActiveSupport::Cache::Strategy::LocalCache
end

Instance Attribute Details

#addressesObject (readonly)

Returns the value of attribute addresses.



17
18
19
# File 'lib/mem_cached_support_store.rb', line 17

def addresses
  @addresses
end

Instance Method Details

#clearObject



117
118
119
120
# File 'lib/mem_cached_support_store.rb', line 117

def clear
  @data.flush
rescue Memcached::NotFound
end

#decrement(key, amount = 1) ⇒ Object

:nodoc:



100
101
102
103
104
105
106
107
108
# File 'lib/mem_cached_support_store.rb', line 100

def decrement(key, amount = 1) # :nodoc:
  log("decrement", key, amount)
  @data.decr(key, amount)
  response
rescue Memcached::NotFound
  nil
rescue Memcached::Error
  nil
end

#delete(key, options = nil) ⇒ Object

:nodoc:



71
72
73
74
75
76
77
78
79
80
# File 'lib/mem_cached_support_store.rb', line 71

def delete(key, options = nil) # :nodoc:
  super
  @data.delete(key)
  true
rescue Memcached::NotFound
  false
rescue Memcached::Error => e
  logger.error("MemcachedError (#{e}): #{e.message}")
  false
end

#delete_matched(matcher, options = nil) ⇒ Object

:nodoc:



110
111
112
113
114
115
# File 'lib/mem_cached_support_store.rb', line 110

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)


82
83
84
85
86
87
# File 'lib/mem_cached_support_store.rb', line 82

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

:nodoc:



89
90
91
92
93
94
95
96
97
98
# File 'lib/mem_cached_support_store.rb', line 89

def increment(key, amount = 1) # :nodoc:
  log("incrementing", key, amount)

  @data.incr(key, amount)
  response
rescue Memcached::NotFound
  nil
rescue Memcached::Error
  nil
end

#read(key, options = nil) ⇒ Object

:nodoc:



38
39
40
41
42
43
44
45
46
# File 'lib/mem_cached_support_store.rb', line 38

def read(key, options = nil) # :nodoc:
  super
  @data.get(key, marshal?(options))
rescue Memcached::NotFound
  nil
rescue Memcached::Error => e
  logger.error("MemcachedError (#{e}): #{e.message}")
  nil
end

#statsObject



122
123
124
125
# File 'lib/mem_cached_support_store.rb', line 122

def stats
  @data.stats
rescue Memcached::NotFound
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.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/mem_cached_support_store.rb', line 55

def write(key, value, options = nil)
  super
  method = options && options[:unless_exist] ? :add : :set
  # memcache-client will break the connection if you send it an integer
  # in raw mode, so we convert it to a string to be sure it continues working.
  @data.send(method, key, value, expires_in(options), marshal?(options))
  true
rescue Memcached::NotStored
  false
rescue Memcached::NotFound
  false
rescue Memcached::Error => e
  logger.error("MemcachedError (#{e}): #{e.message}")
  false
end