Class: ActiveSupport::Cache::DalliStore
- Inherits:
-
Object
- Object
- ActiveSupport::Cache::DalliStore
- Defined in:
- lib/active_support/cache/dalli_store.rb
Defined Under Namespace
Modules: LocalCacheEntryUnwrapAndRaw
Constant Summary collapse
- ESCAPE_KEY_CHARS =
/[\x00-\x20%\x7F-\xFF]/
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#silence ⇒ Object
(also: #silence?)
readonly
Returns the value of attribute silence.
Instance Method Summary collapse
-
#cleanup(options = nil) ⇒ Object
Clear any local cache.
-
#clear(options = nil) ⇒ Object
Clear the entire cache on all memcached servers.
-
#dalli ⇒ Object
Access the underlying Dalli::Client or ConnectionPool instance for access to get_multi, etc.
-
#decrement(name, amount = 1, options = nil) ⇒ Object
Decrement a cached value.
- #delete(name, options = nil) ⇒ Object
- #exist?(name, options = nil) ⇒ Boolean
-
#fetch(name, options = nil) ⇒ Object
Fetch the value associated with the key.
-
#fetch_multi(*names) ⇒ Object
Fetches data from the cache, using the given keys.
-
#increment(name, amount = 1, options = nil) ⇒ Object
Increment a cached value.
-
#initialize(*addresses) ⇒ DalliStore
constructor
Creates a new DalliStore object, with the given memcached server addresses.
- #logger ⇒ Object
- #logger=(new_logger) ⇒ Object
-
#mute ⇒ Object
Silence the logger within a block.
- #read(name, options = nil) ⇒ Object
-
#read_multi(*names) ⇒ Object
Reads multiple keys from the cache using a single call to the servers for all keys.
- #reset ⇒ Object
-
#silence! ⇒ Object
Silence the logger.
-
#stats ⇒ Object
Get the statistics from the memcached servers.
- #with(&block) ⇒ Object
- #write(name, value, options = nil) ⇒ Object
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).
Connection Pool support
If you are using multithreaded Rails, the Rails.cache singleton can become a source of contention. You can use a connection pool of Dalli clients with Rails.cache by passing :pool_size and/or :pool_timeout:
config.cache_store = :dalli_store, ‘localhost:11211’, :pool_size => 10
Both pool options default to 5. You must include the ‘connection_pool` gem if you wish to use pool support.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/active_support/cache/dalli_store.rb', line 48 def initialize(*addresses) addresses = addresses.flatten = addresses. @options = .dup = {} [:size] = [:pool_size] if [:pool_size] [:timeout] = [:pool_timeout] if [:pool_timeout] @options[:compress] ||= @options[:compression] addresses.compact! servers = if addresses.empty? nil # use the default from Dalli::Client else addresses end if .empty? @data = Dalli::Client.new(servers, @options) else @data = ::ConnectionPool.new() { Dalli::Client.new(servers, @options.merge(:threadsafe => false)) } end extend Strategy::LocalCache extend LocalCacheEntryUnwrapAndRaw end |
Instance Attribute Details
#options ⇒ Object (readonly)
Returns the value of attribute options.
9 10 11 |
# File 'lib/active_support/cache/dalli_store.rb', line 9 def @options end |
#silence ⇒ Object (readonly) Also known as: silence?
Returns the value of attribute silence.
9 10 11 |
# File 'lib/active_support/cache/dalli_store.rb', line 9 def silence @silence end |
Instance Method Details
#cleanup(options = nil) ⇒ Object
Clear any local cache
278 279 |
# File 'lib/active_support/cache/dalli_store.rb', line 278 def cleanup(=nil) end |
#clear(options = nil) ⇒ Object
Clear the entire cache on all memcached servers. This method should be used with care when using a shared cache.
266 267 268 269 270 271 272 273 274 275 |
# File 'lib/active_support/cache/dalli_store.rb', line 266 def clear(=nil) instrument_with_log(:clear, 'flushing all keys') do with { |c| c.flush_all } end rescue Dalli::DalliError => e log_dalli_error(e) instrument_error(e) if instrument_errors? raise if raise_errors? nil end |
#dalli ⇒ Object
Access the underlying Dalli::Client or ConnectionPool instance for access to get_multi, etc.
78 79 80 |
# File 'lib/active_support/cache/dalli_store.rb', line 78 def dalli @data end |
#decrement(name, amount = 1, options = nil) ⇒ 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 fail. :initial defaults to zero, as if the counter was initially zero. memcached counters cannot hold negative values.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/active_support/cache/dalli_store.rb', line 249 def decrement(name, amount = 1, =nil) ||= {} name = namespaced_key(name, ) initial = .has_key?(:initial) ? [:initial] : 0 expires_in = [:expires_in] instrument_with_log(:decrement, name, :amount => amount) do with { |c| c.decr(name, amount, expires_in, initial) } end rescue Dalli::DalliError => e log_dalli_error(e) instrument_error(e) if instrument_errors? raise if raise_errors? nil end |
#delete(name, options = nil) ⇒ Object
158 159 160 161 162 163 164 165 |
# File 'lib/active_support/cache/dalli_store.rb', line 158 def delete(name, =nil) ||= {} name = namespaced_key(name, ) instrument_with_log(:delete, name, ) do |payload| delete_entry(name, ) end end |
#exist?(name, options = nil) ⇒ Boolean
150 151 152 153 154 155 156 |
# File 'lib/active_support/cache/dalli_store.rb', line 150 def exist?(name, =nil) ||= {} name = namespaced_key(name, ) log(:exist, name, ) !read_entry(name, ).nil? end |
#fetch(name, options = nil) ⇒ Object
Fetch the value associated with the key. If a value is found, then it is returned.
If a value is not found and no block is given, then nil is returned.
If a value is not found (or if the found value is nil and :cache_nils is false) and a block is given, the block will be invoked and its return value written to the cache and returned.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/active_support/cache/dalli_store.rb', line 94 def fetch(name, =nil) ||= {} [:cache_nils] = true if @options[:cache_nils] namespaced_name = namespaced_key(name, ) not_found = [:cache_nils] ? Dalli::Server::NOT_FOUND : nil if block_given? entry = not_found unless [:force] entry = instrument_with_log(:read, namespaced_name, ) do |payload| read_entry(namespaced_name, ).tap do |result| if payload payload[:super_operation] = :fetch payload[:hit] = not_found != result end end end end if not_found == entry result = instrument_with_log(:generate, namespaced_name, ) do |payload| yield end write(name, result, ) result else instrument_with_log(:fetch_hit, namespaced_name, ) { |payload| } entry end else read(name, ) end end |
#fetch_multi(*names) ⇒ Object
Fetches data from the cache, using the given keys. If there is data in the cache with the given keys, then that data is returned. Otherwise, the supplied block is called for each key for which there was no data, and the result will be written to the cache and returned.
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/active_support/cache/dalli_store.rb', line 199 def fetch_multi(*names) = names. mapping = names.inject({}) { |memo, name| memo[namespaced_key(name, )] = name; memo } instrument_with_log(:fetch_multi, mapping.keys) do with do |connection| results = connection.get_multi(mapping.keys) connection.multi do mapping.inject({}) do |memo, (, name)| memo[name] = results[] if memo[name].nil? value = yield(name) memo[name] = value = .merge(:connection => connection) write_entry(, value, ) end memo end end end end end |
#increment(name, amount = 1, options = nil) ⇒ 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 fail. :initial defaults to the amount passed in, as if the counter was initially zero. memcached counters cannot hold negative values.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/active_support/cache/dalli_store.rb', line 229 def increment(name, amount = 1, =nil) ||= {} name = namespaced_key(name, ) initial = .has_key?(:initial) ? [:initial] : amount expires_in = [:expires_in] instrument_with_log(:increment, name, :amount => amount) do with { |c| c.incr(name, amount, expires_in, initial) } end rescue Dalli::DalliError => e log_dalli_error(e) instrument_error(e) if instrument_errors? raise if raise_errors? nil end |
#logger ⇒ Object
290 291 292 |
# File 'lib/active_support/cache/dalli_store.rb', line 290 def logger Dalli.logger end |
#logger=(new_logger) ⇒ Object
294 295 296 |
# File 'lib/active_support/cache/dalli_store.rb', line 294 def logger=(new_logger) Dalli.logger = new_logger end |
#mute ⇒ Object
Silence the logger within a block.
19 20 21 22 23 24 |
# File 'lib/active_support/cache/dalli_store.rb', line 19 def mute previous_silence, @silence = defined?(@silence) && @silence, true yield ensure @silence = previous_silence end |
#read(name, options = nil) ⇒ Object
127 128 129 130 131 132 133 134 135 136 |
# File 'lib/active_support/cache/dalli_store.rb', line 127 def read(name, =nil) ||= {} name = namespaced_key(name, ) instrument_with_log(:read, name, ) do |payload| entry = read_entry(name, ) payload[:hit] = !entry.nil? if payload entry end end |
#read_multi(*names) ⇒ Object
Reads multiple keys from the cache using a single call to the servers for all keys. Keys must be Strings.
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/active_support/cache/dalli_store.rb', line 169 def read_multi(*names) = names. mapping = names.inject({}) { |memo, name| memo[namespaced_key(name, )] = name; memo } instrument_with_log(:read_multi, mapping.keys) do results = {} if local_cache mapping.each_key do |key| if value = local_cache.read_entry(key, ) results[key] = value end end end data = with { |c| c.get_multi(mapping.keys - results.keys) } results.merge!(data) results.inject({}) do |memo, (inner, _)| entry = results[inner] # NB Backwards data compatibility, to be removed at some point value = (entry.is_a?(ActiveSupport::Cache::Entry) ? entry.value : entry) memo[mapping[inner]] = value local_cache.write_entry(inner, value, ) if local_cache memo end end end |
#reset ⇒ Object
286 287 288 |
# File 'lib/active_support/cache/dalli_store.rb', line 286 def reset with { |c| c.reset } end |
#silence! ⇒ Object
Silence the logger.
13 14 15 16 |
# File 'lib/active_support/cache/dalli_store.rb', line 13 def silence! @silence = true self end |
#stats ⇒ Object
Get the statistics from the memcached servers.
282 283 284 |
# File 'lib/active_support/cache/dalli_store.rb', line 282 def stats with { |c| c.stats } end |
#with(&block) ⇒ Object
82 83 84 |
# File 'lib/active_support/cache/dalli_store.rb', line 82 def with(&block) @data.with(&block) end |
#write(name, value, options = nil) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/active_support/cache/dalli_store.rb', line 138 def write(name, value, =nil) ||= {} name = namespaced_key(name, ) instrument_with_log(:write, name, ) do |payload| with do |connection| = .merge(:connection => connection) write_entry(name, value, ) end end end |