any_cache 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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]