public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
e59de604 » jeremy 2008-01-31 Add a handful of cache stor... 1 require 'benchmark'
b1164add » jeremy 2009-11-08 Fix arg destructure 2 require 'active_support/core_ext/array/wrap'
699d2146 » jeremy 2009-03-28 Explicit class attribute ac... 3 require 'active_support/core_ext/benchmark'
4 require 'active_support/core_ext/exception'
5 require 'active_support/core_ext/class/attribute_accessors'
b540eca5 » jeremy 2009-11-01 Consolidate Object#to_param... 6 require 'active_support/core_ext/object/to_param'
e59de604 » jeremy 2008-01-31 Add a handful of cache stor... 7
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 8 module ActiveSupport
b047929c » lifo 2008-11-01 Merge with docrails 9 # See ActiveSupport::Cache::Store for documentation.
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 10 module Cache
e44076f2 » jeremy 2008-11-23 Autoload cache stores 11 autoload :FileStore, 'active_support/cache/file_store'
12 autoload :MemoryStore, 'active_support/cache/memory_store'
13 autoload :SynchronizedMemoryStore, 'active_support/cache/synchronized_memory_store'
14 autoload :MemCacheStore, 'active_support/cache/mem_cache_store'
15 autoload :CompressedMemCacheStore, 'active_support/cache/compressed_mem_cache_store'
16
b08c9688 » methodmissing 2009-01-17 Decouple the local cache st... Comment 17 module Strategy
18 autoload :LocalCache, 'active_support/cache/strategy/local_cache'
19 end
20
b047929c » lifo 2008-11-01 Merge with docrails 21 # Creates a new CacheStore object according to the given options.
22 #
23 # If no arguments are passed to this method, then a new
24 # ActiveSupport::Cache::MemoryStore object will be returned.
25 #
26 # If you pass a Symbol as the first argument, then a corresponding cache
27 # store class under the ActiveSupport::Cache namespace will be created.
28 # For example:
29 #
30 # ActiveSupport::Cache.lookup_store(:memory_store)
31 # # => returns a new ActiveSupport::Cache::MemoryStore object
32 #
595e0333 » jeremy 2009-04-17 Remove rarely-used DRb cach... 33 # ActiveSupport::Cache.lookup_store(:mem_cache_store)
34 # # => returns a new ActiveSupport::Cache::MemCacheStore object
b047929c » lifo 2008-11-01 Merge with docrails 35 #
36 # Any additional arguments will be passed to the corresponding cache store
37 # class's constructor:
38 #
39 # ActiveSupport::Cache.lookup_store(:file_store, "/tmp/cache")
40 # # => same as: ActiveSupport::Cache::FileStore.new("/tmp/cache")
41 #
42 # If the first argument is not a Symbol, then it will simply be returned:
43 #
44 # ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
45 # # => returns MyOwnCacheStore.new
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 46 def self.lookup_store(*store_option)
b1164add » jeremy 2009-11-08 Fix arg destructure 47 store, *parameters = *Array.wrap(store_option).flatten
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 48
49 case store
50 when Symbol
595e0333 » jeremy 2009-04-17 Remove rarely-used DRb cach... 51 store_class_name = store.to_s.camelize
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 52 store_class = ActiveSupport::Cache.const_get(store_class_name)
53 store_class.new(*parameters)
54 when nil
55 ActiveSupport::Cache::MemoryStore.new
56 else
57 store
58 end
59 end
60
4bf516e0 » wycats 2009-08-10 More perf work: 61 RAILS_CACHE_ID = ENV["RAILS_CACHE_ID"]
62 RAILS_APP_VERION = ENV["RAILS_APP_VERION"]
63 EXPANDED_CACHE = RAILS_CACHE_ID || RAILS_APP_VERION
64
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 65 def self.expand_cache_key(key, namespace = nil)
66 expanded_cache_key = namespace ? "#{namespace}/" : ""
f47c81ff » jeremy 2008-06-20 Fall back to #to_s for cach... Comment 67
4bf516e0 » wycats 2009-08-10 More perf work: 68 if EXPANDED_CACHE
69 expanded_cache_key << "#{RAILS_CACHE_ID || RAILS_APP_VERION}/"
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 70 end
71
4bf516e0 » wycats 2009-08-10 More perf work: 72 expanded_cache_key <<
73 if key.respond_to?(:cache_key)
00ba4c0c » jeremy 2008-06-20 true#to_param => true, so b... 74 key.cache_key
4bf516e0 » wycats 2009-08-10 More perf work: 75 elsif key.is_a?(Array)
76 if key.size > 1
77 key.collect { |element| expand_cache_key(element) }.to_param
78 else
79 key.first.to_param
80 end
81 elsif key
00ba4c0c » jeremy 2008-06-20 true#to_param => true, so b... 82 key.to_param
83 end.to_s
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 84
85 expanded_cache_key
86 end
87
b047929c » lifo 2008-11-01 Merge with docrails 88 # An abstract cache store class. There are multiple cache store
89 # implementations, each having its own additional features. See the classes
90 # under the ActiveSupport::Cache module, e.g.
91 # ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most
92 # popular cache store for large production websites.
93 #
94 # ActiveSupport::Cache::Store is meant for caching strings. Some cache
95 # store implementations, like MemoryStore, are able to cache arbitrary
96 # Ruby objects, but don't count on every cache store to be able to do that.
97 #
98 # cache = ActiveSupport::Cache::MemoryStore.new
99 #
100 # cache.read("city") # => nil
101 # cache.write("city", "Duckburgh")
102 # cache.read("city") # => "Duckburgh"
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 103 class Store
8f59d7a8 » josevalim 2009-10-09 Instrument cache store even... 104 cattr_accessor :logger, :instance_writter => false
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 105
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 106 attr_reader :silence
107 alias :silence? :silence
ee7d4c47 » carlhuda 2009-07-01 Fixes bug where Memcached c... Comment 108
0eef4e55 » josh 2008-07-17 Allow ActiveSupport::Cache ... 109 def silence!
110 @silence = true
111 self
112 end
113
987d5011 » lifo 2009-10-09 Mute log info coming from t... 114 def mute
115 previous_silence, @silence = defined?(@silence) && @silence, true
116 yield
117 ensure
118 @silence = previous_silence
119 end
120
8f59d7a8 » josevalim 2009-10-09 Instrument cache store even... 121 # Set to true if cache stores should be instrumented. By default is false.
122 def self.instrument=(boolean)
123 Thread.current[:instrument_cache_store] = boolean
124 end
125
126 def self.instrument
127 Thread.current[:instrument_cache_store] || false
128 end
129
b047929c » lifo 2008-11-01 Merge with docrails 130 # Fetches data from the cache, using the given key. If there is data in
131 # the cache with the given key, then that data is returned.
132 #
133 # If there is no such data in the cache (a cache miss occurred), then
134 # then nil will be returned. However, if a block has been passed, then
135 # that block will be run in the event of a cache miss. The return value
136 # of the block will be written to the cache under the given cache key,
137 # and that return value will be returned.
138 #
139 # cache.write("today", "Monday")
140 # cache.fetch("today") # => "Monday"
141 #
142 # cache.fetch("city") # => nil
143 # cache.fetch("city") do
144 # "Duckburgh"
145 # end
146 # cache.fetch("city") # => "Duckburgh"
147 #
148 # You may also specify additional options via the +options+ argument.
149 # Setting <tt>:force => true</tt> will force a cache miss:
150 #
151 # cache.write("today", "Monday")
152 # cache.fetch("today", :force => true) # => nil
153 #
154 # Other options will be handled by the specific cache store implementation.
155 # Internally, #fetch calls #read, and calls #write on a cache miss.
156 # +options+ will be passed to the #read and #write calls.
157 #
158 # For example, MemCacheStore's #write method supports the +:expires_in+
159 # option, which tells the memcached server to automatically expire the
b5775c2b » lifo 2009-06-21 Add expiry support File cac... 160 # cache item after a certain period. This options is also supported by
161 # FileStore's #read method. We can use this option with #fetch too:
b047929c » lifo 2008-11-01 Merge with docrails 162 #
163 # cache = ActiveSupport::Cache::MemCacheStore.new
164 # cache.fetch("foo", :force => true, :expires_in => 5.seconds) do
165 # "bar"
166 # end
167 # cache.fetch("foo") # => "bar"
168 # sleep(6)
169 # cache.fetch("foo") # => nil
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 170 def fetch(key, options = {}, &block)
2f7ce08b » jeremy 2008-01-31 cache.fetch(key, :force => ... 171 if !options[:force] && value = read(key, options)
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 172 value
173 elsif block_given?
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 174 result = instrument(:generate, key, options, &block)
175 write(key, result, options)
176 result
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 177 end
178 end
179
b047929c » lifo 2008-11-01 Merge with docrails 180 # Fetches data from the cache, using the given key. If there is data in
181 # the cache with the given key, then that data is returned. Otherwise,
182 # nil is returned.
183 #
184 # You may also specify additional options via the +options+ argument.
185 # The specific cache store implementation will decide what to do with
186 # +options+.
b5775c2b » lifo 2009-06-21 Add expiry support File cac... 187 #
188 # For example, FileStore supports the +:expires_in+ option, which
189 # makes the method return nil for cache items older than the specified
190 # period.
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 191 def read(key, options = nil, &block)
192 instrument(:read, key, options, &block)
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 193 end
194
b047929c » lifo 2008-11-01 Merge with docrails 195 # Writes the given value to the cache, with the given key.
196 #
197 # You may also specify additional options via the +options+ argument.
198 # The specific cache store implementation will decide what to do with
199 # +options+.
200 #
201 # For example, MemCacheStore supports the +:expires_in+ option, which
202 # tells the memcached server to automatically expire the cache item after
203 # a certain period:
204 #
205 # cache = ActiveSupport::Cache::MemCacheStore.new
206 # cache.write("foo", "bar", :expires_in => 5.seconds)
207 # cache.read("foo") # => "bar"
208 # sleep(6)
209 # cache.read("foo") # => nil
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 210 def write(key, value, options = nil, &block)
211 instrument(:write, key, options, &block)
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 212 end
213
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 214 def delete(key, options = nil, &block)
215 instrument(:delete, key, options, &block)
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 216 end
217
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 218 def delete_matched(matcher, options = nil, &block)
219 instrument(:delete_matched, matcher.inspect, options, &block)
99860b72 » josevalim 2008-05-16 Add fragment_exist? and exi... 220 end
221
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 222 def exist?(key, options = nil, &block)
223 instrument(:exist?, key, options, &block)
99860b72 » josevalim 2008-05-16 Add fragment_exist? and exi... 224 end
225
fef82759 » tobi 2008-04-29 Implement increment/decreme... 226 def increment(key, amount = 1)
227 if num = read(key)
228 write(key, num + amount)
229 else
230 nil
231 end
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 232 end
233
fef82759 » tobi 2008-04-29 Implement increment/decreme... 234 def decrement(key, amount = 1)
235 if num = read(key)
236 write(key, num - amount)
237 else
238 nil
239 end
240 end
94cf6675 » josh 2008-07-17 Cleanup ActiveSupport::Cach... 241
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 242 private
b5775c2b » lifo 2009-06-21 Add expiry support File cac... 243 def expires_in(options)
ee7d4c47 » carlhuda 2009-07-01 Fixes bug where Memcached c... Comment 244 expires_in = options && options[:expires_in]
245 raise ":expires_in must be a number" if expires_in && !expires_in.is_a?(Numeric)
246 expires_in || 0
b5775c2b » lifo 2009-06-21 Add expiry support File cac... 247 end
248
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 249 def instrument(operation, key, options, &block)
8f59d7a8 » josevalim 2009-10-09 Instrument cache store even... 250 log(operation, key, options)
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 251
8f59d7a8 » josevalim 2009-10-09 Instrument cache store even... 252 if self.class.instrument
253 payload = { :key => key }
254 payload.merge!(options) if options.is_a?(Hash)
2d7abe24 » josevalim 2009-10-15 Renamed Orchestra to Notifi... 255 ActiveSupport::Notifications.instrument(:"cache_#{operation}", payload, &block)
8f59d7a8 » josevalim 2009-10-09 Instrument cache store even... 256 else
257 yield
258 end
4215e9ab » josevalim 2009-09-20 Instrumenting cache stores. 259 end
260
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 261 def log(operation, key, options)
af0d1fa8 » josevalim 2009-10-07 Update Orchestra instrument... 262 return unless logger && !silence?
263 logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}")
2a9ad9cc » dhh 2008-01-03 Moved the caching stores fr... 264 end
265 end
266 end
267 end