From b5775c2b3efb3ae5ef9074d26f6fc3e302a4f6f0 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sun, 21 Jun 2009 14:35:14 +0100 Subject: Add expiry support File cache store [#1693 state:resolved] [Roman Shterenzon, Pratik Naik] --- activesupport/lib/active_support/cache.rb | 12 ++++++++++-- activesupport/lib/active_support/cache/file_store.rb | 14 +++++++++++++- activesupport/lib/active_support/cache/mem_cache_store.rb | 4 ---- activesupport/test/caching_test.rb | 10 ++++++++++ 4 files changed, 33 insertions(+), 7 deletions(-) (limited to 'activesupport') diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index feb6b1f2cf..192a82e74f 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -129,8 +129,8 @@ module ActiveSupport # # For example, MemCacheStore's #write method supports the +:expires_in+ # option, which tells the memcached server to automatically expire the - # cache item after a certain period. We can use this option with #fetch - # too: + # cache item after a certain period. This options is also supported by + # FileStore's #read method. We can use this option with #fetch too: # # cache = ActiveSupport::Cache::MemCacheStore.new # cache.fetch("foo", :force => true, :expires_in => 5.seconds) do @@ -169,6 +169,10 @@ module ActiveSupport # You may also specify additional options via the +options+ argument. # The specific cache store implementation will decide what to do with # +options+. + # + # For example, FileStore supports the +:expires_in+ option, which + # makes the method return nil for cache items older than the specified + # period. def read(key, options = nil) log("read", key, options) end @@ -223,6 +227,10 @@ module ActiveSupport end private + def expires_in(options) + (options && options[:expires_in]) || 0 + end + def log(operation, key, options) logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !@silence && !@logger_off end diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index 3217350d58..75eed5ed94 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -10,11 +10,23 @@ module ActiveSupport @cache_path = cache_path end + # Reads a value from the cache. + # + # Possible options: + # - +:expires_in+ - the number of seconds that this value may stay in + # the cache. def read(name, options = nil) super - File.open(real_file_path(name), 'rb') { |f| Marshal.load(f) } rescue nil + + file_name = real_file_path(name) + expires = expires_in(options) + + if File.exist?(file_name) && (expires <= 0 || Time.now - File.mtime(file_name) < expires) + File.open(file_name, 'rb') { |f| Marshal.load(f) } + end end + # Writes a value to the cache. def write(name, value, options = nil) super ensure_cache_path(File.dirname(real_file_path(name))) diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index 38b3409ca6..954d0f5423 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -130,10 +130,6 @@ module ActiveSupport end private - def expires_in(options) - (options && options[:expires_in]) || 0 - end - def raw?(options) options && options[:raw] end diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index 51d04d9388..e6e2205708 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -146,6 +146,16 @@ class FileStoreTest < ActiveSupport::TestCase end include CacheStoreBehavior + + def test_expires_in + @cache.write('foo', 'bar') + cache_read = lambda { @cache.read('foo', :expires_in => 2) } + assert_equal 'bar', cache_read.call + sleep(1) + assert_equal 'bar', cache_read.call + sleep(1) + assert_nil cache_read.call + end end class MemoryStoreTest < ActiveSupport::TestCase -- cgit v1.2.3 From 66eb05821b1cb522f497c874e7708fe705fb8356 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sun, 21 Jun 2009 14:51:43 +0100 Subject: Use stubbing instead of sleep() in File store cache tests --- activesupport/test/caching_test.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'activesupport') diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index e6e2205708..c2a03818e1 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -148,12 +148,18 @@ class FileStoreTest < ActiveSupport::TestCase include CacheStoreBehavior def test_expires_in + time = Time.local(2008, 4, 24) + Time.stubs(:now).returns(time) + File.stubs(:mtime).returns(time) + @cache.write('foo', 'bar') - cache_read = lambda { @cache.read('foo', :expires_in => 2) } + cache_read = lambda { @cache.read('foo', :expires_in => 1.minute) } assert_equal 'bar', cache_read.call - sleep(1) + + Time.stubs(:now).returns(time + 30.seconds) assert_equal 'bar', cache_read.call - sleep(1) + + Time.stubs(:now).returns(time + 2.minutes) assert_nil cache_read.call end end -- cgit v1.2.3