any_cache 0.3.1 → 0.4.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.
data/lib/any_cache.rb CHANGED
@@ -10,6 +10,7 @@ require 'concurrent/atomic/reentrant_read_write_lock'
10
10
  class AnyCache
11
11
  require_relative 'any_cache/version'
12
12
  require_relative 'any_cache/error'
13
+ require_relative 'any_cache/dumper'
13
14
  require_relative 'any_cache/drivers'
14
15
  require_relative 'any_cache/adapters'
15
16
  require_relative 'any_cache/logging'
@@ -95,6 +96,7 @@ class AnyCache
95
96
  :expire,
96
97
  :persist,
97
98
  :clear,
99
+ :cleanup,
98
100
  :exist?
99
101
 
100
102
  # @return [AnyCache::Adapters::Basic]
@@ -46,28 +46,28 @@ module AnyCache::Adapters
46
46
  DEAD_TTL = 0
47
47
 
48
48
  # @since 0.3.0
49
- def_delegators :driver, :delete, :clear
49
+ def_delegators :driver, :delete, :clear, :cleanup
50
50
 
51
51
  # @param key [String]
52
- # @param options [Hash]
52
+ # @option raw [Boolean]
53
53
  # @return [void]
54
54
  #
55
55
  # @api private
56
56
  # @since 0.3.0
57
57
  def read(key, **options)
58
- raw = options.fetch(:raw, true)
58
+ raw = options.fetch(:raw, false)
59
59
 
60
60
  driver.read(key, raw: raw)
61
61
  end
62
62
 
63
63
  # @param keys [Array<String>]
64
- # @param options [Hash]
64
+ # @option raw [Boolean]
65
65
  # @return [Hash]
66
66
  #
67
67
  # @api private
68
68
  # @since 0.3.0
69
69
  def read_multi(*keys, **options)
70
- raw = options.fetch(:raw, true)
70
+ raw = options.fetch(:raw, false)
71
71
 
72
72
  driver.read_multi(*keys, raw: raw).tap do |entries|
73
73
  entries.merge!(Hash[(keys - entries.keys).zip(READ_MULTI_EMPTY_KEYS_SET)])
@@ -77,25 +77,26 @@ module AnyCache::Adapters
77
77
  # @param key [String]
78
78
  # @param value [Object]
79
79
  # @option expires_in [NilClass, Integer] Time in seconds
80
+ # @option raw [Boolean]
80
81
  # @return [void]
81
82
  #
82
83
  # @api private
83
84
  # @since 0.3.0
84
85
  def write(key, value, **options)
85
86
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
86
- raw = options.fetch(:raw, true)
87
+ raw = options.fetch(:raw, false)
87
88
 
88
89
  driver.write(key, value, expires_in: expires_in, raw: raw)
89
90
  end
90
91
 
91
92
  # @param entries [Hash]
92
- # @param options [Hash]
93
+ # @option raw [Boolean]
93
94
  # @return [void]
94
95
  #
95
96
  # @api private
96
97
  # @since 0.3.0
97
98
  def write_multi(entries, **options)
98
- raw = options.fetch(:raw, true)
99
+ raw = options.fetch(:raw, false)
99
100
 
100
101
  # NOTE: ActiveSupport::Cache::DalliStore does not support #write_multi :\
101
102
  entries.each_pair do |key, value|
@@ -106,6 +107,7 @@ module AnyCache::Adapters
106
107
  # @param key [String]
107
108
  # @option expires_in [Integer]
108
109
  # @option force [Boolean, Proc]
110
+ # @option raw [Boolean]
109
111
  # @return [Object]
110
112
  #
111
113
  # @api private
@@ -114,8 +116,9 @@ module AnyCache::Adapters
114
116
  force_rewrite = options.fetch(:force, false)
115
117
  force_rewrite = force_rewrite.call(key) if force_rewrite.respond_to?(:call)
116
118
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
119
+ raw = options.fetch(:raw, false)
117
120
 
118
- driver.fetch(key, force: force_rewrite, expires_in: expires_in, &fallback)
121
+ driver.fetch(key, force: force_rewrite, expires_in: expires_in, raw: raw, &fallback)
119
122
  end
120
123
 
121
124
  # @param keys [Array<String>]
@@ -142,7 +145,7 @@ module AnyCache::Adapters
142
145
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
143
146
 
144
147
  unless exist?(key)
145
- write(key, amount, expires_in: expires_in) && amount
148
+ write(key, amount, expires_in: expires_in, raw: true) && amount
146
149
  else
147
150
  driver.increment(key, amount).tap do
148
151
  expire(key, expires_in: expires_in) if expires_in
@@ -165,7 +168,8 @@ module AnyCache::Adapters
165
168
  # - non-raw values;
166
169
  # - values lower than zero;
167
170
  # - empty entries;
168
- write(key, INITIAL_DECREMNETED_VALUE, expires_in: expires_in) && INITIAL_DECREMNETED_VALUE
171
+ write(key, INITIAL_DECREMNETED_VALUE, expires_in: expires_in, raw: true)
172
+ INITIAL_DECREMNETED_VALUE
169
173
  else
170
174
  driver.decrement(key, amount).tap do
171
175
  expire(key, expires_in: expires_in) if expires_in
@@ -190,9 +194,9 @@ module AnyCache::Adapters
190
194
  # @api private
191
195
  # @since 0.3.0
192
196
  def expire(key, expires_in: DEAD_TTL)
193
- read(key).tap do |value|
197
+ read(key, raw: true).tap do |value|
194
198
  is_alive = expires_in ? expires_in.positive? : false
195
- is_alive ? write(key, value, expires_in: expires_in) : delete(key)
199
+ is_alive ? write(key, value, expires_in: expires_in, raw: true) : delete(key)
196
200
  end
197
201
  end
198
202
 
@@ -51,25 +51,25 @@ module AnyCache::Adapters
51
51
  def_delegators :driver, :delete, :clear
52
52
 
53
53
  # @param key [String]
54
- # @param options [Hash]
54
+ # @option raw [Boolean]
55
55
  # @return [Object]
56
56
  #
57
57
  # @api private
58
58
  # @since 0.2.0
59
59
  def read(key, **options)
60
- raw = options.fetch(:raw, true)
60
+ raw = options.fetch(:raw, false)
61
61
 
62
62
  driver.read(key, raw: raw)
63
63
  end
64
64
 
65
65
  # @param keys [Array<String>]
66
- # @param options [Hash]
66
+ # @option raw [Boolean]
67
67
  # @return [Hash]
68
68
  #
69
69
  # @api private
70
70
  # @since 0.3.0
71
71
  def read_multi(*keys, **options)
72
- raw = options.fetch(:raw, true)
72
+ raw = options.fetch(:raw, false)
73
73
 
74
74
  driver.read_multi(*keys, raw: raw).tap do |entries|
75
75
  entries.merge!(Hash[(keys - entries.keys).zip(READ_MULTI_EMPTY_KEYS_SET)])
@@ -79,25 +79,26 @@ module AnyCache::Adapters
79
79
  # @param key [String]
80
80
  # @param value [Object]
81
81
  # @option expires_in [NilClass, Integer] Time in seconds
82
+ # @option raw [Boolean]
82
83
  # @return [void]
83
84
  #
84
85
  # @api private
85
86
  # @sicne 0.2.0
86
87
  def write(key, value, **options)
87
88
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
88
- raw = options.fetch(:raw, true)
89
+ raw = options.fetch(:raw, false)
89
90
 
90
91
  driver.write(key, value, expires_in: expires_in, raw: raw)
91
92
  end
92
93
 
93
94
  # @param entries [Hash]
94
- # @param options [Hash]
95
+ # @option raw [Boolean]
95
96
  # @return [void]
96
97
  #
97
98
  # @api private
98
99
  # @since 0.3.0
99
100
  def write_multi(entries, **options)
100
- raw = options.fetch(:raw, true)
101
+ raw = options.fetch(:raw, false)
101
102
 
102
103
  driver.write_multi(entries, expires_in: NO_EXPIRATION_TTL, raw: raw)
103
104
  end
@@ -105,6 +106,7 @@ module AnyCache::Adapters
105
106
  # @param key [String]
106
107
  # @option expires_in [Integer]
107
108
  # @option force [Boolean, Proc]
109
+ # @option raw [Boolean]
108
110
  # @return [Object]
109
111
  #
110
112
  # @api private
@@ -113,8 +115,9 @@ module AnyCache::Adapters
113
115
  force_rewrite = options.fetch(:force, false)
114
116
  force_rewrite = force_rewrite.call(key) if force_rewrite.respond_to?(:call)
115
117
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
118
+ raw = options.fetch(:raw, false)
116
119
 
117
- driver.fetch(key, force: force_rewrite, expires_in: expires_in, &fallback)
120
+ driver.fetch(key, force: force_rewrite, expires_in: expires_in, raw: raw, &fallback)
118
121
  end
119
122
 
120
123
  # @param keys [Array<String>]
@@ -151,7 +154,7 @@ module AnyCache::Adapters
151
154
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
152
155
 
153
156
  unless exist?(key)
154
- write(key, amount, expires_in: expires_in) && amount
157
+ write(key, amount, expires_in: expires_in, raw: true) && amount
155
158
  else
156
159
  driver.increment(key, amount).tap do
157
160
  expire(key, expires_in: expires_in) if expires_in
@@ -174,7 +177,8 @@ module AnyCache::Adapters
174
177
  # - non-raw values;
175
178
  # - values lower than zero;
176
179
  # - empty entries;
177
- write(key, INITIAL_DECREMNETED_VALUE, expires_in: expires_in) && INITIAL_DECREMNETED_VALUE
180
+ write(key, INITIAL_DECREMNETED_VALUE, expires_in: expires_in, raw: true)
181
+ INITIAL_DECREMNETED_VALUE
178
182
  else
179
183
  driver.decrement(key, amount).tap do
180
184
  expire(key, expires_in: expires_in) if expires_in
@@ -189,9 +193,9 @@ module AnyCache::Adapters
189
193
  # @api private
190
194
  # @since 0.2.0
191
195
  def expire(key, expires_in: DEAD_TTL)
192
- read(key).tap do |value|
196
+ read(key, raw: true).tap do |value|
193
197
  is_alive = expires_in ? expires_in.positive? : false
194
- is_alive ? write(key, value, expires_in: expires_in) : delete(key)
198
+ is_alive ? write(key, value, expires_in: expires_in, raw: true) : delete(key)
195
199
  end
196
200
  end
197
201
 
@@ -214,5 +218,14 @@ module AnyCache::Adapters
214
218
  def exist?(key, **options)
215
219
  driver.exist?(key)
216
220
  end
221
+
222
+ # @param options [Hash]
223
+ # @return [void]
224
+ #
225
+ # @api private
226
+ # @since 0.4.0
227
+ def cleanup(**options)
228
+ # NOTE: manual removing is not supported (memcached doing this by itself)
229
+ end
217
230
  end
218
231
  end
@@ -77,6 +77,15 @@ module AnyCache::Adapters
77
77
  lock.with_write_lock { super }
78
78
  end
79
79
 
80
+ # @param options [Hash]
81
+ # @return [void]
82
+ #
83
+ # @api private
84
+ # @since 0.4.0
85
+ def cleanup(**options)
86
+ lock.with_write_lock { super }
87
+ end
88
+
80
89
  # @param key [String]
81
90
  # @param value [Object]
82
91
  # @param options [Hash]
@@ -23,9 +23,6 @@ module AnyCache::Adapters
23
23
  # @since 0.3.0
24
24
  READ_MULTI_EMPTY_KEYS_SET = [].freeze
25
25
 
26
- # @since 0.1.0
27
- def_delegators :driver, :delete, :delete_matched, :clear
28
-
29
26
  # @return [NilClass]
30
27
  #
31
28
  # @api private
@@ -44,26 +41,29 @@ module AnyCache::Adapters
44
41
  # @since 0.1.0
45
42
  DEFAULT_INCR_DECR_AMOUNT = 1
46
43
 
44
+ # @since 0.1.0
45
+ def_delegators :driver, :delete, :delete_matched, :clear
46
+
47
47
  # @param key [String]
48
- # @param options [Hash]
48
+ # @option raw [Boolean]
49
49
  # @return [Object]
50
50
  #
51
51
  # @api private
52
52
  # @since 0.1.0
53
53
  def read(key, **options)
54
- raw = options.fetch(:raw, true)
54
+ raw = options.fetch(:raw, false)
55
55
 
56
56
  driver.read(key, raw: raw)
57
57
  end
58
58
 
59
59
  # @param keys [Array<String>]
60
- # @param options [Hash]
60
+ # @option raw [Boolean]
61
61
  # @return [Hash]
62
62
  #
63
63
  # @api private
64
64
  # @since 0.3.0
65
65
  def read_multi(*keys, **options)
66
- raw = options.fetch(:raw, true)
66
+ raw = options.fetch(:raw, false)
67
67
 
68
68
  driver.read_multi(*keys, raw: raw).tap do |res|
69
69
  res.merge!(Hash[(keys - res.keys).zip(READ_MULTI_EMPTY_KEYS_SET)])
@@ -73,25 +73,26 @@ module AnyCache::Adapters
73
73
  # @param key [String]
74
74
  # @param value [Object]
75
75
  # @option expires_in [NilClass, Integer] Time in seconds
76
+ # @option raw [Boolean]
76
77
  # @return [void]
77
78
  #
78
79
  # @api private
79
80
  # @since 0.1.0
80
81
  def write(key, value, **options)
81
82
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
82
- raw = options.fetch(:raw, true)
83
+ raw = options.fetch(:raw, false)
83
84
 
84
85
  driver.write(key, value, expires_in: expires_in, raw: raw)
85
86
  end
86
87
 
87
88
  # @param entries [Hash]
88
- # @param options [Hash]
89
+ # @option raw [Boolean]
89
90
  # @return [void]
90
91
  #
91
92
  # @api private
92
93
  # @sicne 0.3.0
93
94
  def write_multi(entries, **options)
94
- raw = options.fetch(:raw, true)
95
+ raw = options.fetch(:raw, false)
95
96
 
96
97
  driver.write_multi(entries, expires_in: NO_EXPIRATION_TTL, raw: raw)
97
98
  end
@@ -100,6 +101,7 @@ module AnyCache::Adapters
100
101
  # @param fallback [Proc]
101
102
  # @option expires_in [Integer]
102
103
  # @option force [Boolean, Proc]
104
+ # @option raw [Boolean]
103
105
  # @return [Object]
104
106
  #
105
107
  # @api private
@@ -108,7 +110,7 @@ module AnyCache::Adapters
108
110
  force_rewrite = options.fetch(:force, false)
109
111
  force_rewrite = force_rewrite.call(key) if force_rewrite.respond_to?(:call)
110
112
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
111
- raw = options.fetch(:raw, true)
113
+ raw = options.fetch(:raw, false)
112
114
 
113
115
  driver.fetch(key, force: force_rewrite, expires_in: expires_in, raw: raw, &fallback)
114
116
  end
@@ -141,7 +143,7 @@ module AnyCache::Adapters
141
143
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
142
144
 
143
145
  unless exist?(key)
144
- write(key, amount, expires_in: expires_in) && amount
146
+ write(key, amount, expires_in: expires_in, raw: true) && amount
145
147
  else
146
148
  driver.increment(key, amount).tap do
147
149
  expire(key, expires_in: expires_in) if expires_in
@@ -160,7 +162,7 @@ module AnyCache::Adapters
160
162
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
161
163
 
162
164
  unless exist?(key)
163
- write(key, -amount, expires_in: expires_in) && -amount
165
+ write(key, -amount, expires_in: expires_in, raw: true) && -amount
164
166
  else
165
167
  driver.decrement(key, amount).tap do
166
168
  expire(key, expires_in: expires_in) if expires_in
@@ -175,9 +177,12 @@ module AnyCache::Adapters
175
177
  # @api private
176
178
  # @since 0.1.0
177
179
  def expire(key, expires_in: DEAD_TTL)
178
- read(key).tap do |value|
180
+ # NOTE:
181
+ # raw is true cuz we want the raw cached value.
182
+ # this raw value would be cached again if needed.
183
+ read(key, raw: true).tap do |value|
179
184
  is_alive = expires_in ? expires_in.positive? : false
180
- is_alive ? write(key, value, expires_in: expires_in) : delete(key)
185
+ is_alive ? write(key, value, expires_in: expires_in, raw: true) : delete(key)
181
186
  end
182
187
  end
183
188
 
@@ -200,5 +205,14 @@ module AnyCache::Adapters
200
205
  def exist?(key, **options)
201
206
  driver.exist?(key)
202
207
  end
208
+
209
+ # @param options [Hash]
210
+ # @return [void]
211
+ #
212
+ # @api private
213
+ # @since 0.4.0
214
+ def cleanup(**options)
215
+ # NOTE: manual removing is not suppored (redis doing this by itself)
216
+ end
203
217
  end
204
218
  end
@@ -6,6 +6,8 @@ module AnyCache::Adapters
6
6
  class Basic
7
7
  # @since 0.1.0
8
8
  extend Forwardable
9
+ # @since 0.4.0
10
+ include AnyCache::Dumper::InterfaceAccessMixin
9
11
 
10
12
  class << self
11
13
  # @param driver [Object]
@@ -167,6 +169,15 @@ module AnyCache::Adapters
167
169
  raise NotImplementedError
168
170
  end
169
171
 
172
+ # @param options [Hash]
173
+ # @return [void]
174
+ #
175
+ # @api private
176
+ # @since 0.4.0
177
+ def cleanup(**options)
178
+ raise NotImplementedError
179
+ end
180
+
170
181
  # @param key [String]
171
182
  # @param options [Hash]
172
183
  # @return [Boolean]
@@ -57,29 +57,46 @@ module AnyCache::Adapters
57
57
  :flush
58
58
 
59
59
  # @param key [String]
60
- # @param options [Hash]
60
+ # @option raw [Boolean]
61
61
  # @return [Object]
62
62
  #
63
63
  # @api private
64
64
  # @since 0.1.0
65
65
  def read(key, **options)
66
- get(key)
66
+ raw = options.fetch(:raw, false)
67
+ value = get(key)
68
+
69
+ raw ? value : detransform_value(value)
67
70
  end
68
71
 
69
72
  # @param keys [Array<String>]
70
- # @param options [Hash]
73
+ # @option raw [Boolean]
71
74
  # @return [Hash]
72
75
  #
73
76
  # @api private
74
77
  # @since 0.3.0
75
78
  def read_multi(*keys, **options)
76
- get_multi(*keys).tap do |res|
77
- res.merge!(Hash[(keys - res.keys).zip(READ_MULTI_EMPTY_KEYS_SET)])
79
+ raw = options.fetch(:raw, false)
80
+
81
+ entries = get_multi(*keys).tap do |res|
82
+ # NOTE:
83
+ # dalli does not return nonexistent entries
84
+ # but we want to be consistent with another cache storages
85
+ # that returns nonexistent antries as { key => nil } pair
86
+ res.merge!(Hash[(keys.map(&:to_s) - res.keys).zip(READ_MULTI_EMPTY_KEYS_SET)])
87
+
88
+ # NOTE:
89
+ # dalli stringifies requred keys but we want to be consistent with symbol keys
90
+ # cuz another cache storages are already consistent
91
+ keys.each { |key| res.key?(key) ? next : (res[key] = res.delete(key.to_s)) }
78
92
  end
93
+
94
+ raw ? entries : detransform_pairset(entries)
79
95
  end
80
96
 
81
97
  # @param key [String]
82
98
  # @param value [Object]
99
+ # @option raw [Boolean]
83
100
  # @option expires_in [Integer]
84
101
  # @return [void]
85
102
  #
@@ -87,7 +104,8 @@ module AnyCache::Adapters
87
104
  # @since 0.1.0
88
105
  def write(key, value, **options)
89
106
  expires_in = options.fetch(:expires_in, NO_EXPIRATION_TTL)
90
- raw = options.fetch(:raw, true)
107
+ raw = options.fetch(:raw, false)
108
+ value = transform_value(value) unless raw
91
109
 
92
110
  set(key, value, expires_in, raw: raw)
93
111
  end
@@ -99,9 +117,7 @@ module AnyCache::Adapters
99
117
  # @api private
100
118
  # @since 0.3.0
101
119
  def write_multi(entries, **options)
102
- raw = options.fetch(:raw, true)
103
-
104
- entries.each_pair { |key, value| write(key, value, raw: raw) }
120
+ entries.each_pair { |key, value| write(key, value, **options) }
105
121
  end
106
122
 
107
123
  # @param key [String]
@@ -117,7 +133,7 @@ module AnyCache::Adapters
117
133
  force_rewrite = force_rewrite.call(key) if force_rewrite.respond_to?(:call)
118
134
 
119
135
  # NOTE: can conflict with :cache_nils Dalli::Client's config
120
- read(key).tap { |value| return value if value } unless force_rewrite
136
+ read(key, **options).tap { |value| return value if value } unless force_rewrite
121
137
 
122
138
  yield(key).tap { |value| write(key, value, **options) } if block_given?
123
139
  end
@@ -219,6 +235,15 @@ module AnyCache::Adapters
219
235
  flush(0) # NOTE: 0 is a flush delay
220
236
  end
221
237
 
238
+ # @param options [Hash]
239
+ # @return [void]
240
+ #
241
+ # @api private
242
+ # @since 0.4.0
243
+ def cleanup(**options)
244
+ # NOTE: manual removing is not suppored (memcached doing it by itself)
245
+ end
246
+
222
247
  # @param key [String]
223
248
  # @param options [Hash]
224
249
  # @return [Boolean]