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 +4 -4
- data/.travis.yml +15 -0
- data/CHANGELOG.md +15 -0
- data/README.md +240 -76
- data/any_cache.gemspec +1 -1
- data/bin/rspec +14 -2
- data/lib/any_cache/adapters/active_support_dalli_store.rb +219 -0
- data/lib/any_cache/adapters/active_support_mem_cache_store.rb +71 -16
- data/lib/any_cache/adapters/active_support_naive_store/operation.rb +6 -0
- data/lib/any_cache/adapters/active_support_naive_store.rb +79 -17
- data/lib/any_cache/adapters/active_support_redis_cache_store.rb +68 -17
- data/lib/any_cache/adapters/basic.rb +52 -10
- data/lib/any_cache/adapters/dalli.rb +81 -17
- data/lib/any_cache/adapters/delegator.rb +10 -0
- data/lib/any_cache/adapters/redis.rb +92 -18
- data/lib/any_cache/adapters/redis_store.rb +23 -0
- data/lib/any_cache/adapters.rb +4 -2
- data/lib/any_cache/delegation.rb +50 -0
- data/lib/any_cache/drivers/active_support_dalli_store.rb +25 -0
- data/lib/any_cache/drivers.rb +5 -0
- data/lib/any_cache/logging/activity.rb +27 -0
- data/lib/any_cache/logging/logger.rb +12 -0
- data/lib/any_cache/logging.rb +8 -0
- data/lib/any_cache/version.rb +1 -1
- data/lib/any_cache.rb +31 -15
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4257f6b3fe2d927086723caf69eec54042cca687633f6737ee42f6604f434a8
|
4
|
+
data.tar.gz: dd574909f6c2668f13f19e97cafb948dd1f8c5b4a284705a221b486ccdf29872
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 · [](https://badge.fury.io/rb/any_cache) [](https://travis-ci.org/0exp/any_cache) [](https://coveralls.io/github/0exp/any_cache)
|
1
|
+
# AnyCache · [](https://badge.fury.io/rb/any_cache) [](https://travis-ci.org/0exp/any_cache) [](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
|
-
#
|
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
|
-
|
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
|
-
- `:
|
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.
|
193
|
-
conf.
|
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(
|
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:], [&
|
375
|
+
- `AnyCache#fetch(key, [force:], [expires_in:], [&fallback])`
|
302
376
|
- works in `ActiveSupport::Cache::Store#fetch`-manner;
|
303
|
-
- fetches data from the cache
|
304
|
-
- if
|
305
|
-
|
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
|
-
|
312
|
-
|
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
|
-
|
316
|
-
|
317
|
-
|
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
|
-
|
321
|
-
|
322
|
-
|
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
|
-
|
396
|
+
cache_store.fetch("data") # => nil
|
325
397
|
|
326
398
|
# --- force update/rewrite ---
|
327
|
-
|
328
|
-
|
329
|
-
|
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
|
-
|
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
|
-
|
452
|
+
cache_store.read("data") # => "some_data"
|
343
453
|
|
344
454
|
# --- entry doesnt exist ---
|
345
|
-
|
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
|
-
|
485
|
+
cache_store.write("data", 123)
|
357
486
|
|
358
487
|
# --- temporal entry (expires in 60 seconds) ---
|
359
|
-
|
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
|
-
|
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
|
-
|
536
|
+
cache_store.write("data", 1)
|
382
537
|
|
383
538
|
# --- increment by default value (1) ---
|
384
|
-
|
539
|
+
cache_store.increment("data") # => 2
|
385
540
|
|
386
541
|
# --- increment by custom value ---
|
387
|
-
|
542
|
+
cache_store.increment("data", 12) # => 14
|
388
543
|
|
389
544
|
# --- increment and expire after 31 seconds
|
390
|
-
|
545
|
+
cache_store.incrmeent("data", expires_in: 31) # => 15
|
391
546
|
|
392
547
|
# --- increment nonexistent entry (create new entry) ---
|
393
|
-
|
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
|
-
|
560
|
+
cache_store.write("data", 15)
|
406
561
|
|
407
562
|
# --- decrement by default value (1) ---
|
408
|
-
|
563
|
+
cache_store.decrement("data") # => 14
|
409
564
|
|
410
565
|
# --- decrement by custom value ---
|
411
|
-
|
566
|
+
cache_store.decrement("data", 10) # => 4
|
412
567
|
|
413
568
|
# --- decrement and expire after 5 seconds
|
414
|
-
|
569
|
+
cache_store.decrememnt("data", expirs_in: 5) # => 3
|
415
570
|
|
416
571
|
# --- decrement nonexistent entry (create new entry) ---
|
417
|
-
|
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
|
-
|
583
|
+
cache_store.expire("data")
|
429
584
|
|
430
585
|
# --- set new expiration time (in seconds) --
|
431
|
-
|
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
|
-
|
597
|
+
cache_store.write("data", { a: 1 }, expires_in: 30)
|
443
598
|
|
444
599
|
# --- remove entry expiration (make it permanent) ---
|
445
|
-
|
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
|
-
|
611
|
+
cache_store.exist?("data") # => true
|
457
612
|
|
458
613
|
# --- entry does not exist ---
|
459
|
-
|
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
|
-
|
471
|
-
|
625
|
+
cache_store.write("data", { a: 1, b: 2 })
|
626
|
+
cache_store.write("another_data", 123_456)
|
472
627
|
|
473
|
-
|
474
|
-
|
628
|
+
cache_store.read("data") # => { a: 1, b: 2 }
|
629
|
+
cache_store.read("another_data") # => 123_456
|
475
630
|
|
476
631
|
# --- clear cache ---
|
477
|
-
|
632
|
+
cache_store.clear
|
478
633
|
|
479
|
-
|
480
|
-
|
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.
|
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'
|