Skip to content

Commit

Permalink
Merge pull request #18 from 0exp/feature/clean-up
Browse files Browse the repository at this point in the history
[cleanup] Remove expired entries
  • Loading branch information
0exp committed Nov 26, 2018
2 parents c5c9e1b + 4fd1f4d commit 62fd379
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog
All notable changes to this project will be documented in this file.

## [Unreleased]
- `AnyCache#cleanup` - remove expired entries manually
(make sence only for `:as_file_store` and `:as_memory_store` at this moment);

## [0.3.1] - 2018-10-08
### Added
- patch interface `AnyCache.enable_patch!(:patch_series_name)`:
Expand Down
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# AnyCache · [![Gem Version](https://badge.fury.io/rb/any_cache.svg)](https://badge.fury.io/rb/any_cache) [![Build Status](https://travis-ci.org/0exp/any_cache.svg?branch=master)](https://travis-ci.org/0exp/any_cache) [![Coverage Status](https://coveralls.io/repos/github/0exp/any_cache/badge.svg?branch=master)](https://coveralls.io/github/0exp/any_cache?branch=master)

AnyCache - a simplest cache wrapper that provides a minimalistic generic interface for all well-known cache storages and includes a minimal set of necessary operations:
`fetch`, `read`, `write`, `delete`, `fetch_multi`, `read_multi`, `write_multi`, `delete_matched`, `expire`, `persist`, `exist?`, `clear`, `increment`, `decrement`.
`fetch`, `read`, `write`, `delete`, `fetch_multi`, `read_multi`, `write_multi`, `delete_matched`, `expire`, `persist`, `exist?`, `clear`, `cleanup`, `increment`, `decrement`.

Supported clients:

Expand Down Expand Up @@ -60,6 +60,7 @@ require 'any_cache'
- [Persist](#persist)
- [Existence](#existence)
- [Clear](#clear)
- [Cleanup](#cleanup)
- [Roadmap](#roadmap)

---
Expand Down Expand Up @@ -290,6 +291,7 @@ If you want to use your own cache client implementation, you should provide an o
- `#persist(key, [**options])` ([doc](#persist))
- `#exist?(key, [**options])` ([doc](#existence))
- `#clear([**options])` ([doc](#clear))
- `#cleanup([**options])` ([doc](#cleanup))

```ruby
class MyCacheClient
Expand Down Expand Up @@ -640,6 +642,21 @@ cache_store.read("another_data") # => nil

---

### Cleanup

- `AnyCache#cleanup()` - remove expired entries from cache database (make sense only for `:as_file_store` and `:as_memory_store` cache clients)

```ruby
# --- prepare cache data ---
cache_store.write("data", "123", expires_in: 5)
cache_store.write("another_data", "456", expires_in: 10)

# --- waiting for cache exiration (10 seconds) ---
cache_store.cleanup # remove expired entries from database (release disk space for example)
```

---

## Build

- see [bin/rspec](bin/rspec)
Expand All @@ -662,6 +679,7 @@ bin/rspec --test-as-memory-store # run specs with ActiveSupport::Cache::MemorySt
- instrumentation layer;
- global and configurable default expiration time;
- `#delete_matched` for memcached-based cache storages;
- generic marshaling;

---

Expand Down
2 changes: 1 addition & 1 deletion any_cache.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
end

spec.add_dependency 'concurrent-ruby', '~> 1.0'
spec.add_dependency 'qonfig', '~> 0.7'
spec.add_dependency 'qonfig', '~> 0.8'

spec.add_development_dependency 'coveralls', '~> 0.8'
spec.add_development_dependency 'simplecov', '~> 0.16'
Expand Down
1 change: 1 addition & 0 deletions lib/any_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def build(driver = Drivers.build(config))
:expire,
:persist,
:clear,
:cleanup,
:exist?

# @return [AnyCache::Adapters::Basic]
Expand Down
2 changes: 1 addition & 1 deletion lib/any_cache/adapters/active_support_dalli_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def supported_driver?(driver)
DEAD_TTL = 0

# @since 0.3.0
def_delegators :driver, :delete, :clear
def_delegators :driver, :delete, :clear, :cleanup

# @param key [String]
# @param options [Hash]
Expand Down
9 changes: 9 additions & 0 deletions lib/any_cache/adapters/active_support_mem_cache_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,14 @@ def persist(key, **options)
def exist?(key, **options)
driver.exist?(key)
end

# @param options [Hash]
# @return [void]
#
# @api private
# @since 0.4.0
def cleanup(**options)
# NOTE: manual removing is not supported (memcached doing this by itself)
end
end
end
9 changes: 9 additions & 0 deletions lib/any_cache/adapters/active_support_naive_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ def clear(**options)
lock.with_write_lock { super }
end

# @param options [Hash]
# @return [void]
#
# @api private
# @since 0.4.0
def cleanup(**options)
lock.with_write_lock { super }
end

# @param key [String]
# @param value [Object]
# @param options [Hash]
Expand Down
15 changes: 12 additions & 3 deletions lib/any_cache/adapters/active_support_redis_cache_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ def supported_driver?(driver)
# @since 0.3.0
READ_MULTI_EMPTY_KEYS_SET = [].freeze

# @since 0.1.0
def_delegators :driver, :delete, :delete_matched, :clear

# @return [NilClass]
#
# @api private
Expand All @@ -44,6 +41,9 @@ def supported_driver?(driver)
# @since 0.1.0
DEFAULT_INCR_DECR_AMOUNT = 1

# @since 0.1.0
def_delegators :driver, :delete, :delete_matched, :clear

# @param key [String]
# @param options [Hash]
# @return [Object]
Expand Down Expand Up @@ -200,5 +200,14 @@ def persist(key, **options)
def exist?(key, **options)
driver.exist?(key)
end

# @param options [Hash]
# @return [void]
#
# @api private
# @since 0.4.0
def cleanup(**options)
# NOTE: manual removing is not suppored (redis doing this by itself)
end
end
end
9 changes: 9 additions & 0 deletions lib/any_cache/adapters/basic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,15 @@ def clear(**options)
raise NotImplementedError
end

# @param options [Hash]
# @return [void]
#
# @api private
# @since 0.4.0
def cleanup(**options)
raise NotImplementedError
end

# @param key [String]
# @param options [Hash]
# @return [Boolean]
Expand Down
9 changes: 9 additions & 0 deletions lib/any_cache/adapters/dalli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,15 @@ def clear(**options)
flush(0) # NOTE: 0 is a flush delay
end

# @param options [Hash]
# @return [void]
#
# @api private
# @since 0.4.0
def cleanup(**options)
# NOTE: manual removing is not suppored (memcached doing it by itself)
end

# @param key [String]
# @param options [Hash]
# @return [Boolean]
Expand Down
10 changes: 6 additions & 4 deletions lib/any_cache/adapters/delegator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def supported_driver?(driver)
driver.respond_to?(:read_multi) &&
driver.respond_to?(:write) &&
driver.respond_to?(:write_multi) &&
driver.respond_to?(:fetch) &&
driver.respond_to?(:fetch_multi) &&
driver.respond_to?(:delete) &&
driver.respond_to?(:delete_matched) &&
Expand All @@ -24,8 +25,8 @@ def supported_driver?(driver)
driver.respond_to?(:expire) &&
driver.respond_to?(:persist) &&
driver.respond_to?(:clear) &&
driver.respond_to?(:exist?) &&
driver.respond_to?(:fetch)
driver.respond_to?(:cleanup) &&
driver.respond_to?(:exist?)
end
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
end
Expand All @@ -36,6 +37,7 @@ def supported_driver?(driver)
:read_multi,
:write,
:write_multi,
:fetch,
:fetch_multi,
:delete,
:delete_matched,
Expand All @@ -44,7 +46,7 @@ def supported_driver?(driver)
:expire,
:persist,
:clear,
:exist?,
:fetch
:cleanup,
:exist?
end
end
9 changes: 9 additions & 0 deletions lib/any_cache/adapters/redis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,15 @@ def clear(**options)
flushdb
end

# @param options [Hash]
# @return [void]
#
# @api private
# @since 0.4.0
def cleanup(**options)
# NOTE: manual removing is not suppored (redis doing this by itself)
end

# @param key [String]
# @param options [Hash]
# @return [Boolean]
Expand Down
57 changes: 57 additions & 0 deletions spec/features/cleanup_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

describe 'Operation: #cleanup' do
include_context 'cache store'

it 'removes expired entries' do
cache_store.write(:key_1, 'key_1_value', expires_in: 4) # 4 seconds lifetime
cache_store.write(:key_2, 'key_2_value', expires_in: 8) # 8 seconds lifetime
cache_store.write(:key_3, 'key_3_value', expires_in: 12) # 12 seconds lifetime
cache_store.write(:key_4, 'key_4_value', expires_in: 16) # 16 seconds lifetime

sleep(1) # 1 second left
cache_store.cleanup
expect(cache_store.fetch_multi(:key_1, :key_2, :key_3, :key_4)).to match(
key_1: 'key_1_value',
key_2: 'key_2_value',
key_3: 'key_3_value',
key_4: 'key_4_value',
)

sleep(3) # 4 seconds left
cache_store.cleanup
expect(cache_store.fetch_multi(:key_1, :key_2, :key_3, :key_4)).to match(
key_1: nil, # expired
key_2: 'key_2_value',
key_3: 'key_3_value',
key_4: 'key_4_value',
)

sleep(4) # 8 seconds left
cache_store.cleanup
expect(cache_store.fetch_multi(:key_1, :key_2, :key_3, :key_4)).to match(
key_1: nil, # expired
key_2: nil, # expired
key_3: 'key_3_value',
key_4: 'key_4_value',
)

sleep(4) # 12 seconds left
cache_store.cleanup
expect(cache_store.fetch_multi(:key_1, :key_2, :key_3, :key_4)).to match(
key_1: nil, # expired
key_2: nil, # expired
key_3: nil, # expired
key_4: 'key_4_value',
)

sleep(4) # 16 seconds left
cache_store.cleanup
expect(cache_store.fetch_multi(:key_1, :key_2, :key_3, :key_4)).to match(
key_1: nil, # expired
key_2: nil, # expired
key_3: nil, # expired
key_4: nil, # expired
)
end
end
4 changes: 4 additions & 0 deletions spec/features/custom_cache_clients_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def decrement(key, value, **); end
def expire(key, **); end
def persist(key, **); end
def clear(key, **); end
def cleanup(**); end
def exist?(key, **); end
# rubocop:enable Layout/EmptyLineBetweenDefs
end.new
Expand All @@ -39,6 +40,7 @@ def decrement; end
def expire; end
def persist; end
def clear; end
def cleanup(**); end
def exist?; end
end.new
# rubocop:enable Layout/EmptyLineBetweenDefs
Expand All @@ -60,6 +62,7 @@ def exist?; end
expire
persist
clear
cleanup
fetch
exist?
].each do |operation|
Expand Down Expand Up @@ -141,6 +144,7 @@ def exist?; end
expire
persist
clear
cleanup
exist?
]
end
Expand Down

0 comments on commit 62fd379

Please sign in to comment.