4 # See ActiveSupport::Cache::Store for documentation.
6 # Creates a new CacheStore object according to the given options.
8 # If no arguments are passed to this method, then a new
9 # ActiveSupport::Cache::MemoryStore object will be returned.
11 # If you pass a Symbol as the first argument, then a corresponding cache
12 # store class under the ActiveSupport::Cache namespace will be created.
15 # ActiveSupport::Cache.lookup_store(:memory_store)
16 # # => returns a new ActiveSupport::Cache::MemoryStore object
18 # ActiveSupport::Cache.lookup_store(:drb_store)
19 # # => returns a new ActiveSupport::Cache::DRbStore object
21 # Any additional arguments will be passed to the corresponding cache store
22 # class's constructor:
24 # ActiveSupport::Cache.lookup_store(:file_store, "/tmp/cache")
25 # # => same as: ActiveSupport::Cache::FileStore.new("/tmp/cache")
27 # If the first argument is not a Symbol, then it will simply be returned:
29 # ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
30 # # => returns MyOwnCacheStore.new
31 def self.lookup_store(*store_option
)
32 store
, *parameters
= *([ store_option
].flatten
)
36 store_class_name
= (store
== :drb_store ? "DRbStore" : store
.to_s
.camelize
)
37 store_class
= ActiveSupport
::Cache.const_get(store_class_name
)
38 store_class
.new(*parameters
)
40 ActiveSupport
::Cache::MemoryStore.new
46 def self.expand_cache_key(key
, namespace
= nil)
47 expanded_cache_key
= namespace
? "#{namespace}/" : ""
49 if ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
50 expanded_cache_key
<< "#{ENV["RAILS_CACHE_ID
"] || ENV["RAILS_APP_VERSION
"]}/"
53 expanded_cache_key
<< case
54 when key
.respond_to
?(:cache_key)
57 key
.collect
{ |element
| expand_cache_key(element
) }.to_param
65 # An abstract cache store class. There are multiple cache store
66 # implementations, each having its own additional features. See the classes
67 # under the ActiveSupport::Cache module, e.g.
68 # ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most
69 # popular cache store for large production websites.
71 # ActiveSupport::Cache::Store is meant for caching strings. Some cache
72 # store implementations, like MemoryStore, are able to cache arbitrary
73 # Ruby objects, but don't count on every cache store to be able to do that.
75 # cache = ActiveSupport::Cache::MemoryStore.new
77 # cache.read("city") # => nil
78 # cache.write("city", "Duckburgh")
79 # cache.read("city") # => "Duckburgh"
81 cattr_accessor
:logger
88 # Fetches data from the cache, using the given key. If there is data in
89 # the cache with the given key, then that data is returned.
91 # If there is no such data in the cache (a cache miss occurred), then
92 # then nil will be returned. However, if a block has been passed, then
93 # that block will be run in the event of a cache miss. The return value
94 # of the block will be written to the cache under the given cache key,
95 # and that return value will be returned.
97 # cache.write("today", "Monday")
98 # cache.fetch("today") # => "Monday"
100 # cache.fetch("city") # => nil
101 # cache.fetch("city") do
104 # cache.fetch("city") # => "Duckburgh"
106 # You may also specify additional options via the +options+ argument.
107 # Setting <tt>:force => true</tt> will force a cache miss:
109 # cache.write("today", "Monday")
110 # cache.fetch("today", :force => true) # => nil
112 # Other options will be handled by the specific cache store implementation.
113 # Internally, #fetch calls #read, and calls #write on a cache miss.
114 # +options+ will be passed to the #read and #write calls.
116 # For example, MemCacheStore's #write method supports the +:expires_in+
117 # option, which tells the memcached server to automatically expire the
118 # cache item after a certain period. We can use this option with #fetch
121 # cache = ActiveSupport::Cache::MemCacheStore.new
122 # cache.fetch("foo", :force => true, :expires_in => 5.seconds) do
125 # cache.fetch("foo") # => "bar"
127 # cache.fetch("foo") # => nil
128 def fetch(key
, options
= {})
130 if !options
[:force] && value
= read(key
, options
)
132 log("hit", key
, options
)
136 log("miss", key
, options
)
139 seconds
= Benchmark
.realtime
{ value
= yield }
142 write(key
, value
, options
)
145 log("write (will save #{'%.2f' % (seconds * 1000)}ms)", key
, nil)
151 # Fetches data from the cache, using the given key. If there is data in
152 # the cache with the given key, then that data is returned. Otherwise,
155 # You may also specify additional options via the +options+ argument.
156 # The specific cache store implementation will decide what to do with
158 def read(key
, options
= nil)
159 log("read", key
, options
)
162 # Writes the given value to the cache, with the given key.
164 # You may also specify additional options via the +options+ argument.
165 # The specific cache store implementation will decide what to do with
168 # For example, MemCacheStore supports the +:expires_in+ option, which
169 # tells the memcached server to automatically expire the cache item after
172 # cache = ActiveSupport::Cache::MemCacheStore.new
173 # cache.write("foo", "bar", :expires_in => 5.seconds)
174 # cache.read("foo") # => "bar"
176 # cache.read("foo") # => nil
177 def write(key
, value
, options
= nil)
178 log("write", key
, options
)
181 def delete(key
, options
= nil)
182 log("delete", key
, options
)
185 def delete_matched(matcher
, options
= nil)
186 log("delete matched", matcher
.inspect
, options
)
189 def exist
?(key
, options
= nil)
190 log("exist?", key
, options
)
193 def increment(key
, amount
= 1)
194 log("incrementing", key
, amount
)
196 write(key
, num
+ amount
)
202 def decrement(key
, amount
= 1)
203 log("decrementing", key
, amount
)
205 write(key
, num
- amount
)
212 def log(operation
, key
, options
)
213 logger
.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !@silence && !@logger_off
219 require 'active_support/cache/file_store'
220 require 'active_support/cache/memory_store'
221 require 'active_support/cache/drb_store'
222 require 'active_support/cache/mem_cache_store'
223 require 'active_support/cache/compressed_mem_cache_store'