any_cache 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb955a7841f5f154dd3a18dcc911333edcf3f9ccc7564c84a8165022cb64e201
4
- data.tar.gz: 85ff1e78b433f11a8b870c49fd012b984491873923be153abf6117c57b757a49
3
+ metadata.gz: b4257f6b3fe2d927086723caf69eec54042cca687633f6737ee42f6604f434a8
4
+ data.tar.gz: dd574909f6c2668f13f19e97cafb948dd1f8c5b4a284705a221b486ccdf29872
5
5
  SHA512:
6
- metadata.gz: aaf92352c50ff3a15610214136f4c8b586786548ee384ec46c377b8f055318060417b0cf14ce9c4522e551b3891a2fe35546570f7ba7bef050faee921b4acbbe
7
- data.tar.gz: 14c37f9ab0c5319408e6366c4bcafacf3eb0f220b621fb7c68325ceac0bed3173953003e1ba052888788e875e98390d21e95588b9d82cddcef361a9b630e51ff
6
+ metadata.gz: 88934a670129cf8a67177471884cc8aa493868c4a0ebe6e73899939d2ffd86c5877341965aba82860752e22fe72fb04abbc51c3e071d6f90507367581cba830c
7
+ data.tar.gz: 676ed5568765a5916992333417503942cb545113aa30241c966b0723b7e521334991c56e008284e9f641db33e368509a8aa244a99658c07ca619ff67ce015c91
data/.travis.yml CHANGED
@@ -70,6 +70,18 @@ matrix:
70
70
  - rvm: ruby-head
71
71
  gemfile: gemfiles/redis_store.gemfile
72
72
  env: TEST_REDIS_STORE_CACHE=true
73
+ - rvm: 2.3.7
74
+ gemfile: gemfiles/active_support_with_dalli.gemfile
75
+ env: TEST_AS_DALLI_STORE=true
76
+ - rvm: 2.4.4
77
+ gemfile: gemfiles/active_support_with_dalli.gemfile
78
+ env: TEST_AS_DALLI_STORE=true
79
+ - rvm: 2.5.1
80
+ gemfile: gemfiles/active_support_with_dalli.gemfile
81
+ env: TEST_AS_DALLI_STORE=true
82
+ - rvm: ruby-head
83
+ gemfile: gemfiles/active_support_with_dalli.gemfile
84
+ env: TEST_AS_DALLI_STORE=true
73
85
  - rvm: 2.3.7
74
86
  gemfile: gemfiles/redis_store.gemfile
75
87
  env: TEST_REDIS_CACHE=true
@@ -94,3 +106,6 @@ matrix:
94
106
  - rvm: ruby-head
95
107
  gemfile: gemfiles/active_support_with_dalli.gemfile
96
108
  env: TEST_AS_MEM_CACHE_STORE_CACHE=true
109
+ notifications:
110
+ slack:
111
+ secure: CRYB00OjJTaAYDPM7VgzdU6kBu0WcgwxyzXR6UTrTklrz3jI8ZRKUxrIqNJXvvYbmQPmnRClCeb1/K865RaH+r6Lc+Fob9mBJrjX2eH8CRtBpn542MgKQcJrJR1rrZnxSq7hAfjzYddtbF/vlzkW5yIRLvtihzY9pP+o9XEJF4mhMZWZw8qeqfK16uDzInYpS7ocw7TjDobKPSpG7SXpm+tVMV+0Wmq/58GZDiHq/vEIPiEegnXEEA6lJao/isZtUGn0YFY+ibQA0MrjnBouIdm4MMkK62ybS8dV/EKT6z0ZuG81VhS8Jb6h8H5j9td8xzjYsHpb1FZE0Rwr8ClWmo2vPRekPxpwqJMBM9lBKJ4Ez7lNWsJP0YkleKfmDEN1KIaMMH4g2YXeTfDagVHc803ooNjCbS1EMA1fZgF77gdlG10sdbyexHkxYxw1rozSa1G6OdDBbKehdaCbqbiqx0unI6gQtENa6ouUiIndZjE/ehcHnP4Y8lFTIbwmvGqborkhsI/0/8X0/Xh6GDypOml3mvKT5u7m0UYBy5lSQpTpmZVz9TV3pId12DM1eObIeWxYRkz+L+7stQBfVAVy8mZFLxm2pmey/Vn5pwAnEwgOBZ5qFPrIEHrjgH91rpdvYVPYswYdGm7WrKPpta4pQhSqDMlKhW1zfk+AMmZ4Yz0=
data/CHANGELOG.md CHANGED
@@ -1,7 +1,22 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.3.0] - 2018-10-06
5
+ ### Added
6
+ - support for `ActiveSupport::Cache::DalliStore` client;
7
+ - multi-operations: `#read_multi`, `#write_multi`, `#fetch_multi`, `#delete_matched`;
8
+ - logging:
9
+ - configuration: `AnyCache.configure { |conf| conf.logger = your_logger_object }`;
10
+ - disable logging: `AnyCache.configure { |conf| conf.logger = nil }`;
11
+ - `::Logger.new(STDOUT)` with `::Logger::INFO` level is used by default (an instance of `AnyCache::Logging::Logger`);
12
+ - log message contains the following information:
13
+ - standard log data (level and time);
14
+ - cache class name;
15
+ - current cache operation (`read`, `write` and etc);
16
+ - cache operation arguments;
17
+
4
18
  ## [0.2.0] - 2018-09-03
19
+ ### Added
5
20
  - fetching operation `AnyCache#fetch(key, force:, expires_in:, &block)`
6
21
  - fetches data from the cache using the given key;
7
22
  - if a block has been passed and data with the given key does not exist -
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
- # 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)](https://coveralls.io/github/0exp/any_cache)
1
+ # 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)
2
2
 
3
3
  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:
4
- `fetch`, `read`, `write`, `delete`, `expire`, `persist`, `exist?`, `clear`, `increment`, `decrement`.
4
+ `fetch`, `read`, `write`, `delete`, `fetch_multi`, `read_multi`, `write_multi`, `delete_matched`, `expire`, `persist`, `exist?`, `clear`, `increment`, `decrement`.
5
5
 
6
6
  Supported clients:
7
7
 
@@ -9,6 +9,7 @@ Supported clients:
9
9
  - `Redis::Store` ([gem redis-store](https://github.com/redis-store/redis-store)) ([redis storage](https://redis.io/))
10
10
  - `Dalli::Client` ([gem dalli](https://github.com/petergoldstein/dalli)) ([memcached storage](https://memcached.org/))
11
11
  - `ActiveSupport::Cache::RedisCacheStore` ([gem activesupport](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/cache/redis_cache_store.rb)) ([redis cache storage](https://api.rubyonrails.org/classes/ActiveSupport/Cache/RedisCacheStore.html))
12
+ - `ActiveSupport::Cache::DalliStore` ([gem dalli](https://github.com/petergoldstein/dalli)) ([dalli store](https://github.com/petergoldstein/dalli/blob/master/lib/active_support/cache/dalli_store.rb))
12
13
  - `ActiveSupport::Cache::MemCacheStore` ([gem activesupport](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/cache/mem_cache_store.rb)) ([memcache storage](https://api.rubyonrails.org/classes/ActiveSupport/Cache/MemCacheStore.html))
13
14
  - `ActiveSupport::Cache::FileStore` ([gem activesupport](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/cache/file_store.rb)) ([file storage](https://api.rubyonrails.org/classes/ActiveSupport/Cache/FileStore.html))
14
15
  - `ActiveSupport::Cache::MemoryStore` ([gem activesupport](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/cache/memory_store.rb)) ([in memory storage](https://api.rubyonrails.org/classes/ActiveSupport/Cache/MemoryStore.html))
@@ -42,18 +43,19 @@ require 'any_cache'
42
43
  - [AnyCache with Redis::Store](#anycache-with-redisstore)
43
44
  - [AnyCache with Dalli::Client](#anycache-with-dalliclient)
44
45
  - [AnyCache with ActiveSupport::Cache::RedisCacheStore](#anycache-with-activesupportcacherediscachestore)
46
+ - [AnyCache with ActiveSupport::Cache::DalliStore](#anycache-with-activesupportcachedallistore)
45
47
  - [AnyCache with ActiveSupport::Cache::MemCacheStore](#anycache-with-activesupportcachememcachestore)
46
48
  - [AnyCache with ActiveSupport::Cache::FileStore](#anycache-with-activesupportcachefilestore)
47
49
  - [AnyCache with ActiveSupport::Cache::MemoryStore](#anycache-with-activesupportcachememorystore)
48
50
  - [Many cache storages](#many-cache-storages)
49
51
  - [Custom cache clients](#custom-cache-clients)
52
+ - [Logging](#logging)
50
53
  - [Operations](#operations)
51
- - [Fetch](#fetch)
52
- - [Read](#read)
53
- - [Write](#write)
54
- - [Delete](#delete)
55
- - [Increment](#increment)
56
- - [Decrement](#decrement)
54
+ - [Fetch](#fetch) / [Fetch Multi](#fetch-multi)
55
+ - [Read](#read) / [Read Multi](#read-multi)
56
+ - [Write](#write) / [Write Multi](#write-multi)
57
+ - [Delete](#delete) / [Delete Matched](#delete-matched)
58
+ - [Increment](#increment) / [Decrement](#decrement)
57
59
  - [Expire](#expire)
58
60
  - [Persist](#persist)
59
61
  - [Existence](#existence)
@@ -72,6 +74,7 @@ Supported clients:
72
74
  - `Redis::Store`
73
75
  - `Dalli::Client`
74
76
  - `ActiveSupport::Cache::RedisCacheStore`
77
+ - `ActiveSupport::Cache::DalliStore`
75
78
  - `ActiveSupport::Cache::MemCacheStore`
76
79
  - `ActiveSupport::Cache::FileStore`
77
80
  - `ActiveSupport::Cache::MemoryStore`
@@ -94,7 +97,9 @@ client = Redis::Store.new(...)
94
97
  client = Dalli::Client.new(...)
95
98
  # -- or --
96
99
  client = ActiveSupport::Cache::RedisCacheStore.new(...)
97
- # --- or ---
100
+ # -- or --
101
+ client = ActiveSupport::Cache::DalliStore.new(...)
102
+ # -- or --
98
103
  client = ActiveSupport::Cache::MemCacheStore.new(...)
99
104
  # -- or --
100
105
  client = ActiveSupport::Cache::FileStore.new(...)
@@ -102,7 +107,7 @@ client = ActiveSupport::Cache::FileStore.new(...)
102
107
  client = ActiveSupport::Cache::MemoryStore.new(...)
103
108
 
104
109
  # 2) build AnyCache instance
105
- any_cache = AnyCache.build(client) # => <AnyCache:0x00007f990527f268 ...>
110
+ cache_store = AnyCache.build(client) # => <AnyCache:0x00007f990527f268 ...>
106
111
  ```
107
112
 
108
113
  #### Config-based creation
@@ -117,9 +122,10 @@ storage instantiation works via `.build` method without explicit attributes.
117
122
  Supported drivers:
118
123
 
119
124
  - `:redis` - [Redis](#anycache-with-redis);
120
- - `:redis_tore` - [Redis::Client](#anycache-with-redisstore);
125
+ - `:redis_store` - [Redis::Client](#anycache-with-redisstore);
121
126
  - `:dalli` - [Dalli::Client](#anycache-with-dalliclient);
122
127
  - `:as_redis_cache_store` - [ActiveSupport::Cache::RedisCacheStore](#anycache-with-activesupportcacherediscachestore);
128
+ - `:as_dalli_store` - [ActiveSupport::Cache::DalliStore](#anycache-with-activesupportcachedallistore);
123
129
  - `:as_mem_cache_store` - [ActiveSupport::Cache::MemCacheStore](#anycache-with-activesupportcachememcachestore);
124
130
  - `:as_file_store` - [ActiveSupport::Cache::FileStore](#anycache-with-activesupportcachefilestore);
125
131
  - `:as_memory_store` - [ActiveSupport::Cache::MemoryStore](#anycache-with-activesupportcachememorystore);
@@ -135,7 +141,7 @@ AnyCache.configure do |conf|
135
141
  conf.redis.options = { ... } # Redis-related options
136
142
  end
137
143
 
138
- AnyCache.build
144
+ cache_store = AnyCache.build
139
145
  ```
140
146
 
141
147
  ##### `AnyCache` with `Redis::Store`:
@@ -149,7 +155,7 @@ AnyCache.configure do |conf|
149
155
  conf.redis_store.options = { ... } # Redis::Store-related options
150
156
  end
151
157
 
152
- AnyCache.build
158
+ cache_store = AnyCache.build
153
159
  ```
154
160
 
155
161
  ##### `AnyCache` with `Dalli::Client`:
@@ -164,12 +170,13 @@ AnyCache.configure do |conf|
164
170
  conf.dalli.options = { ... } # Dalli::Client-related options
165
171
  end
166
172
 
167
- AnyCache.build
173
+ cache_store = AnyCache.build
168
174
  ```
169
175
 
170
176
  ##### `AnyCache` with `ActiveSupport::Cache::RedisCacheStore`:
171
177
 
172
178
  ```ruby
179
+ require 'redis'
173
180
  require 'active_support'
174
181
  require 'any_cache'
175
182
 
@@ -178,7 +185,23 @@ AnyCache.configure do |conf|
178
185
  conf.as_redis_cache_store.options = { ... } # ActiveSupport::Cache::RedisCacheStore-related options
179
186
  end
180
187
 
181
- AnyCache.build
188
+ cache_store = AnyCache.build
189
+ ```
190
+
191
+ ##### `AnyCache` with `ActiveSupport::Cache::DalliStore`:
192
+
193
+ ```ruby
194
+ require 'dalli'
195
+ require 'active_support'
196
+ require 'any_cache'
197
+
198
+ AnyCache.configure do |conf|
199
+ conf.driver = :as_dalli_store
200
+ conf.as_dalli_store.servers = ... # string or array of strings
201
+ conf.as_dalli_store.options = { ... } # ActiveSupport::Cache::DalliStore-related options
202
+ end
203
+
204
+ cache_store = AnyCache.build
182
205
  ```
183
206
 
184
207
  ##### `AnyCache` with `ActiveSupport::Cache::MemCacheStore`:
@@ -189,11 +212,11 @@ require 'any_cache'
189
212
 
190
213
  AnyCache.configure do |conf|
191
214
  conf.driver = :as_mem_cache_store
192
- conf.as_memory_store.servers = ... # string or array of strings
193
- conf.as_memory_store.options = { ... } # ActiveSupport::Cache::MemCacheStore-related options
215
+ conf.as_mem_cache_store.servers = ... # string or array of strings
216
+ conf.as_mem_cache_store.options = { ... } # ActiveSupport::Cache::MemCacheStore-related options
194
217
  end
195
218
 
196
- AnyCache.build
219
+ cache_store = AnyCache.build
197
220
  ```
198
221
 
199
222
  ##### `AnyCache` with `ActiveSupport::Cache::FileStore`:
@@ -208,7 +231,7 @@ AnyCache.configure do |conf|
208
231
  conf.as_file_store.options = { ... } # ActiveSupport::Cache::FileStore-related options
209
232
  end
210
233
 
211
- AnyCache.build
234
+ cache_store = AnyCache.build
212
235
  ```
213
236
 
214
237
  ##### `AnyCache` with `ActiveSupport::Cache::MemoryStore`:
@@ -222,7 +245,7 @@ AnyCache.configure do |conf|
222
245
  conf.as_memory_store.options = { ... } # ActiveSupport::Cache::MemoryStore-related options
223
246
  end
224
247
 
225
- AnyCache.build
248
+ cache_store = AnyCache.build
226
249
  ```
227
250
 
228
251
  #### Many cache storages
@@ -250,10 +273,14 @@ dalli_cache = DalliCache.build
250
273
 
251
274
  If you want to use your own cache client implementation, you should provide an object that responds to:
252
275
 
253
- - `#fetch(*key, [**options])` ([doc](#fetch))
276
+ - `#fetch(key, [**options])` ([doc](#fetch))
277
+ - `#fetch_multi(*keys, [**options])` ([doc](#fetch-multi))
254
278
  - `#read(key, [**options])` ([doc](#read))
279
+ - `#read_multi(*keys, [**options])` ([doc](#read-multi))
255
280
  - `#write(key, value, [**options])` ([doc](#write))
281
+ - `#write_multi(entries, [**options])` ([doc](#write-multi))
256
282
  - `#delete(key, [**options])` ([doc](#delete))
283
+ - `#delete_matched(pattern, [**options])` ([doc](#delete-matched))
257
284
  - `#increment(key, amount, [**options])` ([doc](#increment))
258
285
  - `#decrement(key, amount, [**options])` ([doc](#decrement))
259
286
  - `#expire(key, [**options])` ([doc](#expire))
@@ -279,16 +306,63 @@ end
279
306
  AnyCache.build(MyCacheClient.new)
280
307
  ```
281
308
 
309
+ ---
310
+
311
+ ### Logging
312
+
313
+ AnyCache logs all its operations. By default, `AnyCache` uses a simple `STDOUT` logger with `Logger::INFO` level.
314
+ Logging is performed with level configured in logger object.
315
+
316
+ Logger configuration:
317
+
318
+ ```ruby
319
+ # --- use your own logger ---
320
+ AnyCache.configure do |conf|
321
+ conf.logger = MyLoggerObject.new
322
+ end
323
+
324
+ # --- disable logging ---
325
+ AnyCache.configure do |conf|
326
+ conf.logger = nil
327
+ end
328
+
329
+ # --- (used by default) ---
330
+ AnyCache.configure do |conf|
331
+ conf.logger = AnyCache::Logging::Logger.new(STDOUT)
332
+ end
333
+ ```
334
+
335
+ Log message format:
336
+
337
+ ```shell
338
+ [AnyCache<CACHER_NAME>/Activity<OPERATION_NAME>]: performed <OPERATION_NAME> operation with
339
+ params: INSPECTED_ARGUMENTS and options: INSPECTED_OPTIONS
340
+ ```
341
+
342
+ - progname
343
+ - `CACHER_NAME` - class name of your cache class;
344
+ - `OPERATION_NAME` - performed operation (`read`, `write`, `fetch` and etc);
345
+ - message
346
+ - `INSPECTED_ARGUMENTS` - a set of operation arguments;
347
+ - `INSPECTED_OPTIONS` - a set of operation options;
348
+
349
+ ```ruby
350
+ any_cache.write("data", 123, expires_in: 60)
351
+ # I, [2018-09-07T10:04:56.649960 #15761] INFO -- [AnyCache<AnyCache>/Activity<write>]: performed <write> operation with params: ["data", 123] and options: {:expires_in=>60}.
352
+
353
+ any_cache.clear
354
+ # I, [2018-09-07T10:05:26.999847 #15761] INFO -- [AnyCache<AnyCache>/Activity<clear>]: performed <clear> operation with params: [] and options: {}.
355
+ ```
356
+
282
357
  ## Operations
283
358
 
284
359
  `AnyCache` provides a following operation set:
285
360
 
286
- - [fetch](#fetch)
287
- - [read](#read)
288
- - [write](#write)
289
- - [delete](#delete)
290
- - [increment](#increment)
291
- - [decrement](#decrement)
361
+ - [fetch](#fetch) / [fetch_multi](#fetch-multi)
362
+ - [read](#read) / [read_multi](#read-multi)
363
+ - [write](#write) / [write_multi](#write-multi)
364
+ - [delete](#delete) / [delete_matched](#delete-matched)
365
+ - [increment](#increment) / [decrement](#decrement)
292
366
  - [expire](#expire)
293
367
  - [persist](#persist)
294
368
  - [clear](#clear)
@@ -298,37 +372,73 @@ AnyCache.build(MyCacheClient.new)
298
372
 
299
373
  ### Fetch
300
374
 
301
- - `AnyCache#fetch(key, [force:], [expires_in:], [&block])`
375
+ - `AnyCache#fetch(key, [force:], [expires_in:], [&fallback])`
302
376
  - works in `ActiveSupport::Cache::Store#fetch`-manner;
303
- - fetches data from the cache, using the given key;
304
- - if there is data in the cache with the given key, then that data is returned;
305
- - if there is no such data in the cache (a cache miss), then nil will be returned:
306
- - if a block has been passed, that block will be passed the key and executed in the event of a cache miss;
307
- - the return value of the block will be written to the cache under the given cache key, and that return value will be returned;
377
+ - fetches data from the cache using the given key;
378
+ - if a `fallback` block has been passed and data with the given key does not exist - that block
379
+ will be called with the given key and the return value will be written to the cache;
308
380
 
309
381
  ```ruby
310
382
  # --- entry exists ---
311
- any_cache.fetch("data") # => "some_data"
312
- any_cache.fetch("data") { "new_data" } # => "some_data"
383
+ cache_store.fetch("data") # => "some_data"
384
+ cache_store.fetch("data") { "new_data" } # => "some_data"
313
385
 
314
386
  # --- entry does not exist ---
315
- any_cache.fetch("data") # => nil
316
- any_cache.fetch("data") { "new_data" } # => "new_data"
317
- any_cache.fetch("data") # => "new_data"
387
+ cache_store.fetch("data") # => nil
388
+ cache_store.fetch("data") { |key| "new_data" } # => "new_data"
389
+ cache_store.fetch("data") # => "new_data"
318
390
 
319
391
  # --- new entry with expiration time ---
320
- any_cache.fetch("data") # => nil
321
- any_cache.fetch("data", expires_in: 8) { "new_data" } # => "new_data"
322
- any_cache.fetch("data") # => "new_data"
392
+ cache_store.fetch("data") # => nil
393
+ cache_store.fetch("data", expires_in: 8) { |key| "new_#{key}" } # => "new_data"
394
+ cache_store.fetch("data") # => "new_data"
323
395
  # ...sleep 8 seconds...
324
- any_cache.fetch("data") # => nil
396
+ cache_store.fetch("data") # => nil
325
397
 
326
398
  # --- force update/rewrite ---
327
- any_cache.fetch("data") # => "some_data"
328
- any_cache.fetch("data", expires_in: 8, force: true) { "new_data" } # => "new_data"
329
- any_cache.fetch("data") # => "new_data"
399
+ cache_store.fetch("data") # => "some_data"
400
+ cache_store.fetch("data", expires_in: 8, force: true) { |key| "new_#{key}" } # => "new_data"
401
+ cache_store.fetch("data") # => "new_data"
330
402
  # ...sleep 8 seconds...
331
- any_cache.fetch("data") # => nil
403
+ cache_store.fetch("data") # => nil
404
+ ```
405
+
406
+ ---
407
+
408
+ ### Fetch Multi
409
+
410
+ - `AnyCache#fetch_multi(*keys, [force:], [expires_in:], [&fallback])`
411
+ - get a set of entries in hash form from the cache storage using given keys;
412
+ - works in `#fetch` manner but with a series of entries;
413
+ - nonexistent entries will be fetched with `nil` values;
414
+
415
+ ```ruby
416
+ # --- fetch entries ---
417
+ cache_store.fetch_multi("data", "second_data", "last_data")
418
+ # => returns:
419
+ {
420
+ "data" => "data", # existing entry
421
+ "second_data" => nil, # nonexistent entry
422
+ "last_data" => nil # nonexistent entry
423
+ }
424
+
425
+ # --- fetch etnries and define non-existent entries ---
426
+ cache_store.fetch_multi("data", "second_data", "last_data") { |key| "new_#{key}" }
427
+ # => returns:
428
+ {
429
+ "data" => "data", # entry with OLD value
430
+ "second_data" => "new_second_data", # entry with NEW DEFINED value
431
+ "last_data" => "new_last_data" # entry with NEW DEFINED value
432
+ }
433
+
434
+ # --- force rewrite all entries ---
435
+ cache_store.fetch_multi("data", "second_data", "last_data", force: true) { |key| "force_#{key}" }
436
+ # => returns
437
+ {
438
+ "data" => "force_data", # entry with REDEFINED value
439
+ "second_data" => "force_second_data", # entry with REDEFINED value
440
+ "last_data" => "force_last_data" # entry with REDEFINED value
441
+ }
332
442
  ```
333
443
 
334
444
  ---
@@ -339,10 +449,29 @@ any_cache.fetch("data") # => nil
339
449
 
340
450
  ```ruby
341
451
  # --- entry exists ---
342
- any_cache.read("data") # => "some_data"
452
+ cache_store.read("data") # => "some_data"
343
453
 
344
454
  # --- entry doesnt exist ---
345
- any_cache.read("data") # => nil
455
+ cache_store.read("data") # => nil
456
+ ```
457
+
458
+ ---
459
+
460
+ ### Read Multi
461
+
462
+ - `AnyCache#read_multi(*keys)`
463
+ - get entries from the cache storage in hash form;
464
+ - nonexistent entries will be fetched with `nil` values;
465
+
466
+ ```ruby
467
+ cache_store.read_multi("data", "another_data", "last_data", "super_data")
468
+ # => returns
469
+ {
470
+ "data" => "test", # existing entry
471
+ "another_data" => nil, # nonexistent entry
472
+ "last_data" => "some_data", # exisitng enry
473
+ "super_data" => nil # existing entry
474
+ }
346
475
  ```
347
476
 
348
477
  ---
@@ -353,10 +482,20 @@ any_cache.read("data") # => nil
353
482
 
354
483
  ```ruby
355
484
  # --- permanent entry ---
356
- any_cache.write("data", 123)
485
+ cache_store.write("data", 123)
357
486
 
358
487
  # --- temporal entry (expires in 60 seconds) ---
359
- any_cache.write("data", 123, expires_in: 60)
488
+ cache_store.write("data", 123, expires_in: 60)
489
+ ```
490
+
491
+ ---
492
+
493
+ ### Write Multi
494
+
495
+ - `AnyCache#write_multi(**entries)` - write a set of permanent entries to the cache storage
496
+
497
+ ```ruby
498
+ cache_store.write_multi("data" => "test", "another_data" => 123)
360
499
  ```
361
500
 
362
501
  ---
@@ -366,7 +505,23 @@ any_cache.write("data", 123, expires_in: 60)
366
505
  - `AnyCache#delete(key)` - remove entry from the cache storage
367
506
 
368
507
  ```ruby
369
- any_cache.delete("data")
508
+ cache_store.delete("data")
509
+ ```
510
+
511
+ ---
512
+
513
+ ### Delete Matched
514
+
515
+ - `AnyCache#delete_matched(pattern)`
516
+ - removes all entries with keys matching the pattern;
517
+ - currently unsupported: `:dalli`, `:as_mem_cache_store`, `:as_dalli_Store`;
518
+
519
+ ```ruby
520
+ # --- using a regepx ---
521
+ cache_store.delete_matched(/\A*test*\z/i)
522
+
523
+ # --- using a string ---
524
+ cache_store.delete_matched("data")
370
525
  ```
371
526
 
372
527
  ---
@@ -378,19 +533,19 @@ any_cache.delete("data")
378
533
 
379
534
  ```ruby
380
535
  # --- increment existing entry ---
381
- any_cache.write("data", 1)
536
+ cache_store.write("data", 1)
382
537
 
383
538
  # --- increment by default value (1) ---
384
- any_cache.increment("data") # => 2
539
+ cache_store.increment("data") # => 2
385
540
 
386
541
  # --- increment by custom value ---
387
- any_cache.increment("data", 12) # => 14
542
+ cache_store.increment("data", 12) # => 14
388
543
 
389
544
  # --- increment and expire after 31 seconds
390
- any_cache.incrmeent("data", expires_in: 31) # => 15
545
+ cache_store.incrmeent("data", expires_in: 31) # => 15
391
546
 
392
547
  # --- increment nonexistent entry (create new entry) ---
393
- any_cache.increment("another_data", 5, expires_in: 5) # => 5
548
+ cache_store.increment("another_data", 5, expires_in: 5) # => 5
394
549
  ```
395
550
 
396
551
  ---
@@ -402,19 +557,19 @@ any_cache.increment("another_data", 5, expires_in: 5) # => 5
402
557
 
403
558
  ```ruby
404
559
  # --- decrement existing entry ---
405
- any_cache.write("data", 15)
560
+ cache_store.write("data", 15)
406
561
 
407
562
  # --- decrement by default value (1) ---
408
- any_cache.decrement("data") # => 14
563
+ cache_store.decrement("data") # => 14
409
564
 
410
565
  # --- decrement by custom value ---
411
- any_cache.decrement("data", 10) # => 4
566
+ cache_store.decrement("data", 10) # => 4
412
567
 
413
568
  # --- decrement and expire after 5 seconds
414
- any_cache.decrememnt("data", expirs_in: 5) # => 3
569
+ cache_store.decrememnt("data", expirs_in: 5) # => 3
415
570
 
416
571
  # --- decrement nonexistent entry (create new entry) ---
417
- any_cache.decrememnt("another_data", 2, expires_in: 10) # => -2 (or 0 for Dalli::Client)
572
+ cache_store.decrememnt("another_data", 2, expires_in: 10) # => -2 (or 0 for Dalli::Client)
418
573
  ```
419
574
 
420
575
  ---
@@ -425,10 +580,10 @@ any_cache.decrememnt("another_data", 2, expires_in: 10) # => -2 (or 0 for Dalli:
425
580
 
426
581
  ```ruby
427
582
  # --- expire immediately ---
428
- any_cache.expire("data")
583
+ cache_store.expire("data")
429
584
 
430
585
  # --- set new expiration time (in seconds) --
431
- any_cache.expire("data", expires_in: 36)
586
+ cache_store.expire("data", expires_in: 36)
432
587
  ```
433
588
 
434
589
  ---
@@ -439,10 +594,10 @@ any_cache.expire("data", expires_in: 36)
439
594
 
440
595
  ```ruby
441
596
  # --- create temporal entry (30 seconds) ---
442
- any_cache.write("data", { a: 1 }, expires_in: 30)
597
+ cache_store.write("data", { a: 1 }, expires_in: 30)
443
598
 
444
599
  # --- remove entry expiration (make it permanent) ---
445
- any_cache.persist("data")
600
+ cache_store.persist("data")
446
601
  ```
447
602
 
448
603
  ---
@@ -453,10 +608,10 @@ any_cache.persist("data")
453
608
 
454
609
  ```ruby
455
610
  # --- entry exists ---
456
- any_cache.exist?("data") # => true
611
+ cache_store.exist?("data") # => true
457
612
 
458
613
  # --- entry does not exist ---
459
- any_cache.exist?("another-data") # => false
614
+ cache_store.exist?("another-data") # => false
460
615
  ```
461
616
 
462
617
  ---
@@ -467,17 +622,17 @@ any_cache.exist?("another-data") # => false
467
622
 
468
623
  ```ruby
469
624
  # --- prepare cache data ---
470
- any_cache.write("data", { a: 1, b: 2 })
471
- any_cache.write("another_data", 123_456)
625
+ cache_store.write("data", { a: 1, b: 2 })
626
+ cache_store.write("another_data", 123_456)
472
627
 
473
- any_cache.read("data") # => { a: 1, b: 2 }
474
- any_cache.read("another_data") # => 123_456
628
+ cache_store.read("data") # => { a: 1, b: 2 }
629
+ cache_store.read("another_data") # => 123_456
475
630
 
476
631
  # --- clear cache ---
477
- any_cache.clear
632
+ cache_store.clear
478
633
 
479
- any_cache.read("data") # => nil
480
- any_cache.read("another_data") # => nil
634
+ cache_store.read("data") # => nil
635
+ cache_store.read("another_data") # => nil
481
636
  ```
482
637
 
483
638
  ---
@@ -490,14 +645,23 @@ any_cache.read("another_data") # => nil
490
645
  bin/rspec --test-redis # run specs with Redis
491
646
  bin/rspec --test-redis-store # run specs with Redis::Store
492
647
  bin/rspec --test-dalli # run specs with Dalli::Client
493
- bin/rspec --test-as-file-store # run specs with ActiveSupport::Cache::FileStore
494
- bin/rspec --test-as-memory-store # run specs with ActiveSupport::Cache::MemoryStore
495
648
  bin/rspec --test-as-redis-cache-store # run specs with ActiveSupport::Cache::RedisCacheStore
649
+ bin/rspec --test-as-dalli-store # run specs with ActiveSupport::Cache::DalliStore
496
650
  bin/rspec --test-as-mem-cache-store # run specs with ActiveSupport::Cache::MemCacheStore
651
+ bin/rspec --test-as-file-store # run specs with ActiveSupport::Cache::FileStore
652
+ bin/rspec --test-as-memory-store # run specs with ActiveSupport::Cache::MemoryStore
497
653
  ```
498
654
 
499
655
  ---
500
656
 
657
+ ## Roadmap
658
+
659
+ - instrumentation layer;
660
+ - global and configurable default expiration time;
661
+ - `#delete_matched` for memcached-based cache storages;
662
+
663
+ ---
664
+
501
665
  ## Contributing
502
666
 
503
667
  - Fork it (https://github.com/0exp/any_cache/fork)
data/any_cache.gemspec CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
 
33
33
  spec.add_development_dependency 'coveralls', '~> 0.8'
34
34
  spec.add_development_dependency 'simplecov', '~> 0.16'
35
- spec.add_development_dependency 'armitage-rubocop', '~> 0.7'
35
+ spec.add_development_dependency 'armitage-rubocop', '~> 0.9'
36
36
  spec.add_development_dependency 'rspec', '~> 3.8'
37
37
 
38
38
  spec.add_development_dependency 'bundler'
data/bin/rspec CHANGED
@@ -20,7 +20,7 @@ module AnyCacheSpecRunner
20
20
  active_support_with_dalli: expand_gemfile_path('active_support_with_dalli.gemfile')
21
21
  }.freeze
22
22
 
23
- # rubocop:disable Metrics/MethodLength, Metrics/BlockLength
23
+ # rubocop:disable Metrics/MethodLength, Metrics/BlockLength, Metrics/AbcSize
24
24
  def run!
25
25
  OptionParser.new do |opts|
26
26
  opts.banner = 'Usage: bin/rspec [options]'
@@ -60,13 +60,18 @@ module AnyCacheSpecRunner
60
60
  'Run specs with ActiveSupport::Cache::MemCacheStore cache storage'
61
61
  ) { run_as_mem_cache_store_cache_specs! }
62
62
 
63
+ opts.on(
64
+ '--test-as-dalli-store',
65
+ 'Run specs with ActiveSupport::Cache::DalliStore cache storage'
66
+ ) { run_as_dalli_store_specs! }
67
+
63
68
  opts.on(
64
69
  '-h', '--help',
65
70
  'Show this message'
66
71
  ) { puts opts }
67
72
  end.parse!
68
73
  end
69
- # rubocop:enable Metrics/MethodLength, Metrics/BlockLength
74
+ # rubocop:enable Metrics/MethodLength, Metrics/BlockLength, Metrics/AbcSize
70
75
 
71
76
  private
72
77
 
@@ -119,6 +124,13 @@ module AnyCacheSpecRunner
119
124
  run_tests!
120
125
  end
121
126
 
127
+ def run_as_dalli_store_specs!
128
+ ENV['TEST_AS_DALLI_STORE'] = 'true'
129
+ ENV['BUNDLE_GEMFILE'] = GEMFILES[:active_support_with_dalli]
130
+
131
+ run_tests!
132
+ end
133
+
122
134
  def run_tests!
123
135
  require 'rubygems'
124
136
  require 'bundler/setup'