Skip to content

Commit

Permalink
Merge pull request #3395 from bdurand/fix_file_store_cleanup
Browse files Browse the repository at this point in the history
Fix ActiveSupport::Cache::FileStore.cleanup to actually work.
  • Loading branch information
josevalim committed Oct 21, 2011
2 parents b838570 + ec93f36 commit 79d01a8
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
21 changes: 18 additions & 3 deletions activesupport/lib/active_support/cache/file_store.rb
Expand Up @@ -26,11 +26,26 @@ def clear(options = nil)
FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)}) FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)})
end end


# Cleanup the cache by removing old entries. By default this will delete entries
# that haven't been accessed in one day. You can change this behavior by passing
# in a +not_accessed_in+ option. Any entry not accessed in that number of seconds
# in the past will be deleted. Alternatively, you can pass in +:expired_only+ with
# +true+ to only delete expired entries.
def cleanup(options = nil) def cleanup(options = nil)
options = merged_options(options) options = merged_options(options)
each_key(options) do |key| expired_only = options[:expired_only]
entry = read_entry(key, options) timestamp = Time.now - (options[:not_accessed_in] || 1.day.to_i)
delete_entry(key, options) if entry && entry.expired? search_dir(cache_path) do |fname|
if expired_only
key = file_path_key(fname)
entry = read_entry(key, options)
delete_entry(key, options) if entry && entry.expired?
else
if File.atime(fname) <= timestamp
key = file_path_key(fname)
delete_entry(key, options)
end
end
end end
end end


Expand Down
34 changes: 34 additions & 0 deletions activesupport/test/caching_test.rb
Expand Up @@ -557,6 +557,29 @@ def test_key_transformation_with_pathname
key = @cache_with_pathname.send(:key_file_path, "views/index?id=1") key = @cache_with_pathname.send(:key_file_path, "views/index?id=1")
assert_equal "views/index?id=1", @cache_with_pathname.send(:file_path_key, key) assert_equal "views/index?id=1", @cache_with_pathname.send(:file_path_key, key)
end end

def test_cleanup_with_not_accessed_in
@cache.write(1, "aaaaaaaaaa")
@cache.write(2, "bbbbbbbbbb")
@cache.write(3, "cccccccccc")
sleep(2)
@cache.read(2)
@cache.cleanup(:not_accessed_in => 1)
assert_equal false, @cache.exist?(1)
assert_equal true, @cache.exist?(2)
assert_equal false, @cache.exist?(3)
end

def test_cleanup_with_expired_only
@cache.write(1, "aaaaaaaaaa", :expires_in => 0.001)
@cache.write(2, "bbbbbbbbbb")
@cache.write(3, "cccccccccc", :expires_in => 0.001)
sleep(0.002)
@cache.cleanup(:expired_only => 0.001)
assert_equal false, @cache.exist?(1)
assert_equal true, @cache.exist?(2)
assert_equal false, @cache.exist?(3)
end


# Because file systems have a maximum filename size, filenames > max size should be split in to directories # Because file systems have a maximum filename size, filenames > max size should be split in to directories
# If filename is 'AAAAB', where max size is 4, the returned path should be AAAA/B # If filename is 'AAAAB', where max size is 4, the returned path should be AAAA/B
Expand Down Expand Up @@ -646,6 +669,17 @@ def @cache.delete_entry (*args)
assert_equal true, @cache.exist?(2) assert_equal true, @cache.exist?(2)
assert_equal false, @cache.exist?(1) assert_equal false, @cache.exist?(1)
end end

def test_cleanup_removes_expired_entries
@cache.write(1, "aaaaaaaaaa", :expires_in => 0.001)
@cache.write(2, "bbbbbbbbbb")
@cache.write(3, "cccccccccc", :expires_in => 0.001)
sleep(0.002)
@cache.cleanup
assert_equal false, @cache.exist?(1)
assert_equal true, @cache.exist?(2)
assert_equal false, @cache.exist?(3)
end
end end


uses_memcached 'memcached backed store' do uses_memcached 'memcached backed store' do
Expand Down
6 changes: 5 additions & 1 deletion railties/guides/source/caching_with_rails.textile
Expand Up @@ -289,7 +289,11 @@ ActionController::Base.cache_store = :file_store, "/path/to/cache/directory"


With this cache store, multiple server processes on the same host can share a cache. Servers processes running on different hosts could share a cache by using a shared file system, but that set up would not be ideal and is not recommended. The cache store is appropriate for low to medium traffic sites that are served off one or two hosts. With this cache store, multiple server processes on the same host can share a cache. Servers processes running on different hosts could share a cache by using a shared file system, but that set up would not be ideal and is not recommended. The cache store is appropriate for low to medium traffic sites that are served off one or two hosts.


Note that the cache will grow until the disk is full unless you periodically clear out old entries. Note that the cache will grow until the disk is full unless you periodically clear out old entries. You can call +ActiveSupport::Cache::FileStore#cleanup+ to remove entries older than a specified time.

<ruby>
Rails.cache.cleanup(:not_accessed_in => 2.days)
</ruby>


h4. ActiveSupport::Cache::MemCacheStore h4. ActiveSupport::Cache::MemCacheStore


Expand Down

0 comments on commit 79d01a8

Please sign in to comment.