any_cache 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -2
  3. data/.rspec +1 -1
  4. data/.rubocop.yml +18 -0
  5. data/.travis.yml +83 -4
  6. data/CHANGELOG.md +5 -0
  7. data/Gemfile +4 -2
  8. data/README.md +241 -18
  9. data/Rakefile +6 -4
  10. data/any_cache.gemspec +21 -7
  11. data/bin/console +5 -11
  12. data/bin/rspec +119 -0
  13. data/gemfiles/active_support.gemfile +7 -0
  14. data/gemfiles/active_support_with_redis.gemfile +8 -0
  15. data/gemfiles/dalli.gemfile +7 -0
  16. data/gemfiles/redis.gemfile +7 -0
  17. data/gemfiles/redis_store.gemfile +7 -0
  18. data/lib/any_cache.rb +49 -3
  19. data/lib/any_cache/adapters.rb +40 -0
  20. data/lib/any_cache/adapters/active_support_file_store.rb +26 -0
  21. data/lib/any_cache/adapters/active_support_file_store/decrement.rb +10 -0
  22. data/lib/any_cache/adapters/active_support_file_store/expire.rb +10 -0
  23. data/lib/any_cache/adapters/active_support_file_store/fetching.rb +28 -0
  24. data/lib/any_cache/adapters/active_support_file_store/increment.rb +10 -0
  25. data/lib/any_cache/adapters/active_support_file_store/operation.rb +10 -0
  26. data/lib/any_cache/adapters/active_support_file_store/persist.rb +10 -0
  27. data/lib/any_cache/adapters/active_support_memory_store.rb +26 -0
  28. data/lib/any_cache/adapters/active_support_memory_store/decrement.rb +10 -0
  29. data/lib/any_cache/adapters/active_support_memory_store/expire.rb +10 -0
  30. data/lib/any_cache/adapters/active_support_memory_store/fetching.rb +16 -0
  31. data/lib/any_cache/adapters/active_support_memory_store/increment.rb +10 -0
  32. data/lib/any_cache/adapters/active_support_memory_store/operation.rb +10 -0
  33. data/lib/any_cache/adapters/active_support_memory_store/persist.rb +10 -0
  34. data/lib/any_cache/adapters/active_support_naive_store.rb +150 -0
  35. data/lib/any_cache/adapters/active_support_naive_store/decrement.rb +72 -0
  36. data/lib/any_cache/adapters/active_support_naive_store/expire.rb +25 -0
  37. data/lib/any_cache/adapters/active_support_naive_store/increment.rb +71 -0
  38. data/lib/any_cache/adapters/active_support_naive_store/operation.rb +64 -0
  39. data/lib/any_cache/adapters/active_support_naive_store/persist.rb +22 -0
  40. data/lib/any_cache/adapters/active_support_redis_cache_store.rb +129 -0
  41. data/lib/any_cache/adapters/basic.rb +118 -0
  42. data/lib/any_cache/adapters/dalli.rb +140 -0
  43. data/lib/any_cache/adapters/delegator.rb +36 -0
  44. data/lib/any_cache/adapters/redis.rb +151 -0
  45. data/lib/any_cache/adapters/redis_store.rb +41 -0
  46. data/lib/any_cache/error.rb +11 -0
  47. data/lib/any_cache/version.rb +5 -2
  48. metadata +127 -5
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
3
2
 
4
- RSpec::Core::RakeTask.new(:spec)
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
5
 
6
- task :default => :spec
6
+ RSpec::Core::RakeTask.new(:rspec)
7
+
8
+ task default: :rspec
data/any_cache.gemspec CHANGED
@@ -1,18 +1,24 @@
1
- lib = File.expand_path("../lib", __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "any_cache/version"
5
+ require 'any_cache/version'
4
6
 
5
7
  Gem::Specification.new do |spec|
6
- spec.name = "any_cache"
7
- spec.version = AnyCache::VERSION
8
+ spec.required_ruby_version = '>= 2.3.7'
8
9
 
10
+ spec.name = 'any_cache'
11
+ spec.version = AnyCache::VERSION
9
12
  spec.authors = ['Rustam Ibragimov']
10
13
  spec.email = ['iamdaiver@icloud.com']
11
- spec.summary = 'Soon'
12
- spec.description = 'Soon'
14
+
15
+ spec.summary = 'AnyCache - a simplest cache wrapper'
16
+ spec.description = 'AnyCache - a simplest cache wrapper that provides ' \
17
+ 'a minimalistic generic interface for the all well-known ' \
18
+ 'cache storages and includes a minimal set of necessary operations.'
19
+
13
20
  spec.homepage = 'https://github.com/0exp/any_cache'
14
21
  spec.license = 'MIT'
15
-
16
22
  spec.bindir = 'bin'
17
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
24
  spec.require_paths = ['lib']
@@ -21,6 +27,14 @@ Gem::Specification.new do |spec|
21
27
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|features)/}) }
22
28
  end
23
29
 
30
+ spec.add_dependency 'concurrent-ruby', '~> 1.0'
31
+
32
+ spec.add_development_dependency 'coveralls', '~> 0.8'
33
+ spec.add_development_dependency 'simplecov', '~> 0.16'
34
+ spec.add_development_dependency 'armitage-rubocop', '~> 0.6'
35
+ spec.add_development_dependency 'rspec', '~> 3.8'
36
+ spec.add_development_dependency 'qonfig', '~> 0.6'
37
+
24
38
  spec.add_development_dependency 'bundler'
25
39
  spec.add_development_dependency 'rake'
26
40
  spec.add_development_dependency 'pry'
data/bin/console CHANGED
@@ -1,14 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "any_cache"
4
+ require 'bundler/setup'
5
+ require 'any_cache'
5
6
 
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
7
+ require 'pry'
8
+ Pry.start
data/bin/rspec ADDED
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'pathname'
5
+ require 'optparse'
6
+
7
+ module AnyCacheSpecRunner
8
+ extend self
9
+
10
+ def expand_gemfile_path(gemfile_name)
11
+ File.expand_path(
12
+ File.join('..', '..', 'gemfiles', gemfile_name),
13
+ Pathname.new(__FILE__).realpath
14
+ )
15
+ end
16
+
17
+ GEMFILES = {
18
+ redis: expand_gemfile_path('redis.gemfile'),
19
+ redis_store: expand_gemfile_path('redis_store.gemfile'),
20
+ dalli: expand_gemfile_path('dalli.gemfile'),
21
+ active_support_with_redis: expand_gemfile_path('active_support_with_redis.gemfile'),
22
+ active_support: expand_gemfile_path('active_support.gemfile')
23
+ }.freeze
24
+
25
+ # rubocop:disable Metrics/MethodLength, Metrics/BlockLength
26
+ def run!
27
+ OptionParser.new do |opts|
28
+ opts.banner = 'Usage: bin/rspec [options]'
29
+
30
+ opts.on(
31
+ '--test-redis',
32
+ 'Run specs with Redis cache storage'
33
+ ) { run_redis_cache_specs! }
34
+
35
+ opts.on(
36
+ '--test-redis-store',
37
+ 'Run specs with Redis::Store cache storage'
38
+ ) { run_redis_store_cache_specs! }
39
+
40
+ opts.on(
41
+ '--test-dalli',
42
+ 'Run specs with Dalli spec storage'
43
+ ) { run_dalli_cache_specs! }
44
+
45
+ opts.on(
46
+ '--test-as-redis-cache-store',
47
+ 'Run specs with ActiveSupport::Cache::RedisCacheStore cache storage'
48
+ ) { run_as_redis_cache_store_cache_specs! }
49
+
50
+ opts.on(
51
+ '--test-as-file-store',
52
+ 'Run specs with ActiveSupport::Cache::FileStore cache storage'
53
+ ) { run_as_file_store_cache_specs! }
54
+
55
+ opts.on(
56
+ '--test-as-memory-store',
57
+ 'Run specs with ActiveSupport::Cache::MemoryStore cache storage'
58
+ ) { run_as_memory_store_cache_specs! }
59
+
60
+ opts.on(
61
+ '-h', '--help',
62
+ 'Show this message'
63
+ ) { puts opts }
64
+ end.parse!
65
+ end
66
+ # rubocop:enable Metrics/MethodLength, Metrics/BlockLength
67
+
68
+ private
69
+
70
+ def run_redis_cache_specs!
71
+ ENV['TEST_REDIS_CACHE'] = 'true'
72
+ ENV['BUNDLE_GEMFILE'] = GEMFILES[:redis]
73
+
74
+ run_tests!
75
+ end
76
+
77
+ def run_redis_store_cache_specs!
78
+ ENV['TEST_REDIS_STORE_CACHE'] = 'true'
79
+ ENV['BUNDLE_GEMFILE'] = GEMFILES[:redis_store]
80
+
81
+ run_tests!
82
+ end
83
+
84
+ def run_dalli_cache_specs!
85
+ ENV['TEST_DALLI_CACHE'] = 'true'
86
+ ENV['BUNDLE_GEMFILE'] = GEMFILES[:dalli]
87
+
88
+ run_tests!
89
+ end
90
+
91
+ def run_as_redis_cache_store_cache_specs!
92
+ ENV['TEST_AS_REDIS_CACHE_STORE_CACHE'] = 'true'
93
+ ENV['BUNDLE_GEMFILE'] = GEMFILES[:active_support_with_redis]
94
+
95
+ run_tests!
96
+ end
97
+
98
+ def run_as_file_store_cache_specs!
99
+ ENV['TEST_AS_FILE_STORE_CACHE'] = 'true'
100
+ ENV['BUNDLE_GEMFILE'] = GEMFILES[:active_support]
101
+
102
+ run_tests!
103
+ end
104
+
105
+ def run_as_memory_store_cache_specs!
106
+ ENV['TEST_AS_MEMORY_STORE_CACHE'] = 'true'
107
+ ENV['BUNDLE_GEMFILE'] = GEMFILES[:active_support]
108
+
109
+ run_tests!
110
+ end
111
+
112
+ def run_tests!
113
+ require 'rubygems'
114
+ require 'bundler/setup'
115
+ load Gem.bin_path('rspec-core', 'rspec')
116
+ end
117
+ end
118
+
119
+ AnyCacheSpecRunner.run!
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'activesupport', '~> 5.2'
6
+
7
+ gemspec path: '..'
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'redis', '~> 4.0'
6
+ gem 'activesupport', '~> 5.2'
7
+
8
+ gemspec path: '..'
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'dalli', '~> 2.7'
6
+
7
+ gemspec path: '..'
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'redis', '~> 4.0'
6
+
7
+ gemspec path: '..'
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'redis-store', '~> 1.5'
6
+
7
+ gemspec path: '..'
data/lib/any_cache.rb CHANGED
@@ -1,5 +1,51 @@
1
- require "any_cache/version"
1
+ # frozen_string_literal: true
2
2
 
3
- module AnyCache
4
- # Your code goes here...
3
+ require 'securerandom'
4
+ require 'concurrent/atomic/reentrant_read_write_lock'
5
+
6
+ # @api public
7
+ # @since 0.1.0
8
+ class AnyCache
9
+ require_relative 'any_cache/version'
10
+ require_relative 'any_cache/adapters'
11
+
12
+ # @since 0.1.0
13
+ extend Forwardable
14
+
15
+ class << self
16
+ # @param driver [Object]
17
+ # @return [AnyCache]
18
+ #
19
+ # @api private
20
+ # @since 0.1.0
21
+ def build(driver)
22
+ new(Adapters.build(driver))
23
+ end
24
+ end
25
+
26
+ # @since 0.1.0
27
+ def_delegators :adapter,
28
+ :read,
29
+ :write,
30
+ :delete,
31
+ :increment,
32
+ :decrement,
33
+ :expire,
34
+ :persist,
35
+ :clear
36
+
37
+ # @return [AnyCache::Adapters::Basic]
38
+ #
39
+ # @api private
40
+ # @since 0.1.0
41
+ attr_reader :adapter
42
+
43
+ # @param adapter [AnyCache::Adapters::Basic]
44
+ # @return [void]
45
+ #
46
+ # @api private
47
+ # @since 0.1.0
48
+ def initialize(adapter)
49
+ @adapter = adapter
50
+ end
5
51
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.1.0
5
+ module AnyCache::Adapters
6
+ require_relative 'adapters/basic'
7
+ require_relative 'adapters/delegator'
8
+ require_relative 'adapters/dalli'
9
+ require_relative 'adapters/redis'
10
+ require_relative 'adapters/redis_store'
11
+ require_relative 'adapters/active_support_naive_store'
12
+ require_relative 'adapters/active_support_file_store'
13
+ require_relative 'adapters/active_support_redis_cache_store'
14
+ require_relative 'adapters/active_support_memory_store'
15
+
16
+ class << self
17
+ # @param driver [Object]
18
+ # @return [AnyCache::Adapters::Basic]
19
+ #
20
+ # @raise [AnyCache::UnsupportedCacheDriverError]
21
+ #
22
+ # @api private
23
+ # @since 0.1.0
24
+ # rubocop:disable Metrics/LineLength
25
+ def build(driver)
26
+ case
27
+ when RedisStore.supported_driver?(driver) then RedisStore.new(driver)
28
+ when Redis.supported_driver?(driver) then Redis.new(driver)
29
+ when Dalli.supported_driver?(driver) then Dalli.new(driver)
30
+ when ActiveSupportRedisCacheStore.supported_driver?(driver) then ActiveSupportRedisCacheStore.new(driver)
31
+ when ActiveSupportMemoryStore.supported_driver?(driver) then ActiveSupportMemoryStore.new(driver)
32
+ when ActiveSupportFileStore.supported_driver?(driver) then ActiveSupportFileStore.new(driver)
33
+ when Delegator.supported_driver?(driver) then Delegator.new(driver)
34
+ else
35
+ raise AnyCache::UnsupportedCacheDriverError
36
+ end
37
+ end
38
+ # rubocop:enable Metrics/LineLength
39
+ end
40
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnyCache::Adapters
4
+ # @api private
5
+ # @since 0.1.0
6
+ class ActiveSupportFileStore < ActiveSupportNaiveStore
7
+ require_relative 'active_support_file_store/fetching'
8
+ require_relative 'active_support_file_store/operation'
9
+ require_relative 'active_support_file_store/increment'
10
+ require_relative 'active_support_file_store/decrement'
11
+ require_relative 'active_support_file_store/expire'
12
+ require_relative 'active_support_file_store/persist'
13
+
14
+ class << self
15
+ # @param driver [Object]
16
+ # @return [Boolean]
17
+ #
18
+ # @api private
19
+ # @since 0.1.0
20
+ def supported_driver?(driver)
21
+ defined?(::ActiveSupport::Cache::FileStore) &&
22
+ driver.is_a?(::ActiveSupport::Cache::FileStore)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnyCache::Adapters
4
+ # @api private
5
+ # @since 0.1.0
6
+ class ActiveSupportFileStore::Decrement < ActiveSupportNaiveStore::Decrement
7
+ # @since 0.1.0
8
+ include ActiveSupportFileStore::Fetching
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnyCache::Adapters
4
+ # @api private
5
+ # @since 0.1.0
6
+ class ActiveSupportFileStore::Expire < ActiveSupportNaiveStore::Expire
7
+ # @since 0.1.0
8
+ include ActiveSupportFileStore::Fetching
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AnyCache::Adapters::ActiveSupportFileStore
4
+ # @api private
5
+ # @since 0.1.0
6
+ module Fetching
7
+ # @param key [String]
8
+ # @return [NilClass, ActiveSupport::Cache::Entry]
9
+ #
10
+ # @api private
11
+ # @since 0.1.0
12
+ def fetch_entry(key)
13
+ driver.instance_eval do
14
+ read_options = merged_options(nil)
15
+ searched_entry = nil
16
+
17
+ search_dir(cache_path) do |fname|
18
+ entry_object = read_entry(fname, read_options)
19
+ entry_name = file_path_key(fname)
20
+
21
+ searched_entry = entry_object if entry_name == key
22
+ end
23
+
24
+ searched_entry
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnyCache::Adapters
4
+ # @api private
5
+ # @since 0.1.0
6
+ class ActiveSupportFileStore::Increment < ActiveSupportNaiveStore::Increment
7
+ # @since 0.1.0
8
+ include ActiveSupportFileStore::Fetching
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AnyCache::Adapters
4
+ # @api private
5
+ # @since 0.1.0
6
+ class ActiveSupportFileStore::Operation < ActiveSupportNaiveStore::Operation
7
+ # @since 0.1.0
8
+ include ActiveSupportFileStore::Fetching
9
+ end
10
+ end