redis-activesupport 5.0.1 → 5.0.2
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 +0 -2
- data/Gemfile +0 -4
- data/README.md +3 -1
- data/lib/active_support/cache/redis_store.rb +25 -13
- data/redis-activesupport.gemspec +3 -4
- data/test/active_support/cache/redis_store_test.rb +72 -2
- metadata +31 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f76cc8e43f05938df0720d314014293a6f1fca07
|
4
|
+
data.tar.gz: 9e1058563ccda4f656c8f124c615997c52d05291
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff1a913f4f8cdbba56665589c487f9def5e02f527b9fa20f06786aaabd0bd97abd4f3d2833639e55b892862fee72671e9aa6e967f9147de0fa380cf5b7e6cdad
|
7
|
+
data.tar.gz: 9edd85a05fd26962dae0a831f6ad1f74d165e6f3399f0e8d42135bb4394da96f7559faef00fa2bd6b9fbb12087fe04be57a08e892f3c8f99cbd6fe67bfebc3ef
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -31,7 +31,9 @@ If you are on **Snow Leopard** you have to run `env ARCHFLAGS="-arch x86_64" bun
|
|
31
31
|
|
32
32
|
## Status
|
33
33
|
|
34
|
-
[](http://badge.fury.io/rb/redis-activesupport)
|
34
|
+
[](http://badge.fury.io/rb/redis-activesupport)
|
35
|
+
[](http://travis-ci.org/redis-store/redis-activesupport?branch=master)
|
36
|
+
[](https://codeclimate.com/github/redis-store/redis-activesupport)
|
35
37
|
|
36
38
|
## Copyright
|
37
39
|
|
@@ -35,6 +35,7 @@ module ActiveSupport
|
|
35
35
|
# # => supply an existing connection pool (e.g. for use with redis-sentinel or redis-failover)
|
36
36
|
def initialize(*addresses)
|
37
37
|
@options = addresses.dup.extract_options!
|
38
|
+
addresses = addresses.map(&:dup)
|
38
39
|
|
39
40
|
@data = if @options[:pool]
|
40
41
|
raise "pool must be an instance of ConnectionPool" unless @options[:pool].is_a?(ConnectionPool)
|
@@ -57,16 +58,22 @@ module ActiveSupport
|
|
57
58
|
options = merged_options(options)
|
58
59
|
instrument(:write, name, options) do |payload|
|
59
60
|
entry = options[:raw].present? ? value : Entry.new(value, options)
|
61
|
+
if options[:expires_in].present? && options[:race_condition_ttl].present? && options[:raw].blank?
|
62
|
+
options[:expires_in] = options[:expires_in].to_f + options[:race_condition_ttl].to_f
|
63
|
+
end
|
60
64
|
write_entry(normalize_key(name, options), entry, options)
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
64
68
|
# Delete objects for matched keys.
|
65
69
|
#
|
70
|
+
# Uses SCAN to iterate and collect matched keys only when both client and
|
71
|
+
# server supports it (Redis server >= 2.8.0, client >= 3.0.6)
|
72
|
+
#
|
66
73
|
# Performance note: this operation can be dangerous for large production
|
67
|
-
# databases, as it uses the Redis "KEYS" command, which
|
68
|
-
# total number of keys in the database. Users of large
|
69
|
-
# avoid this method.
|
74
|
+
# databases on Redis < 2.8.0, as it uses the Redis "KEYS" command, which
|
75
|
+
# is O(N) over the total number of keys in the database. Users of large
|
76
|
+
# Redis caches should avoid this method.
|
70
77
|
#
|
71
78
|
# Example:
|
72
79
|
# cache.delete_matched "rab*"
|
@@ -76,7 +83,17 @@ module ActiveSupport
|
|
76
83
|
matcher = key_matcher(matcher, options)
|
77
84
|
begin
|
78
85
|
with do |store|
|
79
|
-
|
86
|
+
supports_scan_each = store.respond_to?(:supports_redis_version?) &&
|
87
|
+
store.supports_redis_version?("2.8.0") &&
|
88
|
+
store.respond_to?(:scan_each)
|
89
|
+
|
90
|
+
if supports_scan_each
|
91
|
+
keys = store.scan_each(match: matcher).to_a
|
92
|
+
else
|
93
|
+
keys = store.keys(matcher)
|
94
|
+
end
|
95
|
+
|
96
|
+
!keys.empty? && store.del(*keys)
|
80
97
|
end
|
81
98
|
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Redis::CannotConnectError
|
82
99
|
raise if raise_errors?
|
@@ -98,9 +115,6 @@ module ActiveSupport
|
|
98
115
|
values = with { |c| c.mget(*keys) }
|
99
116
|
values.map! { |v| v.is_a?(ActiveSupport::Cache::Entry) ? v.value : v }
|
100
117
|
|
101
|
-
# Remove the options hash before mapping keys to values
|
102
|
-
names.extract_options!
|
103
|
-
|
104
118
|
result = Hash[names.zip(values)]
|
105
119
|
result.reject!{ |k,v| v.nil? }
|
106
120
|
result
|
@@ -110,10 +124,9 @@ module ActiveSupport
|
|
110
124
|
return {} if names == []
|
111
125
|
results = read_multi(*names)
|
112
126
|
options = names.extract_options!
|
113
|
-
fetched = {}
|
114
127
|
need_writes = {}
|
115
128
|
|
116
|
-
fetched = names.inject({}) do |memo,
|
129
|
+
fetched = names.inject({}) do |memo, name|
|
117
130
|
memo[name] = results.fetch(name) do
|
118
131
|
value = yield name
|
119
132
|
need_writes[name] = value
|
@@ -158,7 +171,7 @@ module ActiveSupport
|
|
158
171
|
def increment(key, amount = 1, options = {})
|
159
172
|
options = merged_options(options)
|
160
173
|
instrument(:increment, key, :amount => amount) do
|
161
|
-
with{|c| c.incrby
|
174
|
+
with{|c| c.incrby normalize_key(key, options), amount}
|
162
175
|
end
|
163
176
|
end
|
164
177
|
|
@@ -186,13 +199,13 @@ module ActiveSupport
|
|
186
199
|
def decrement(key, amount = 1, options = {})
|
187
200
|
options = merged_options(options)
|
188
201
|
instrument(:decrement, key, :amount => amount) do
|
189
|
-
with{|c| c.decrby
|
202
|
+
with{|c| c.decrby normalize_key(key, options), amount}
|
190
203
|
end
|
191
204
|
end
|
192
205
|
|
193
206
|
def expire(key, ttl)
|
194
207
|
options = merged_options(nil)
|
195
|
-
with { |c| c.expire
|
208
|
+
with { |c| c.expire normalize_key(key, options), ttl }
|
196
209
|
end
|
197
210
|
|
198
211
|
# Clear all the data from the store.
|
@@ -286,4 +299,3 @@ module ActiveSupport
|
|
286
299
|
end
|
287
300
|
end
|
288
301
|
end
|
289
|
-
|
data/redis-activesupport.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = 'redis-activesupport'
|
6
|
-
s.version = '5.0.
|
6
|
+
s.version = '5.0.2'
|
7
7
|
s.authors = ['Luca Guidi', 'Ryan Bigg']
|
8
8
|
s.email = ['me@lucaguidi.com', 'me@ryanbigg.com']
|
9
9
|
s.homepage = 'http://redis-store.org/redis-activesupport'
|
@@ -18,14 +18,13 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ['lib']
|
20
20
|
|
21
|
-
s.add_runtime_dependency 'redis-store', '~> 1.
|
21
|
+
s.add_runtime_dependency 'redis-store', '~> 1.3.0'
|
22
22
|
s.add_runtime_dependency 'activesupport', '>= 3', '< 6'
|
23
23
|
|
24
24
|
s.add_development_dependency 'rake', '~> 10'
|
25
25
|
s.add_development_dependency 'bundler', '~> 1.3'
|
26
26
|
s.add_development_dependency 'mocha', '~> 0.14.0'
|
27
27
|
s.add_development_dependency 'minitest', '>= 4.2', '< 6'
|
28
|
-
s.add_development_dependency 'connection_pool',
|
28
|
+
s.add_development_dependency 'connection_pool', '~> 2.2.0'
|
29
29
|
s.add_development_dependency 'redis-store-testing'
|
30
30
|
end
|
31
|
-
|
@@ -56,6 +56,20 @@ describe ActiveSupport::Cache::RedisStore do
|
|
56
56
|
redis.exists("rabbit").must_equal(true)
|
57
57
|
end
|
58
58
|
|
59
|
+
it "connects using the passed hash of options" do
|
60
|
+
address = { host: '127.0.0.1', port: '6380', db: '1' }.merge(pool_size: 5, pool_timeout: 10)
|
61
|
+
store = ActiveSupport::Cache::RedisStore.new(address)
|
62
|
+
redis = Redis.new(url: "redis://127.0.0.1:6380/1")
|
63
|
+
redis.flushall
|
64
|
+
address[:db] = '0' # Should not use this db
|
65
|
+
|
66
|
+
store.data.class.must_equal(::ConnectionPool)
|
67
|
+
|
68
|
+
store.write("rabbit", 0)
|
69
|
+
|
70
|
+
redis.exists("rabbit").must_equal(true)
|
71
|
+
end
|
72
|
+
|
59
73
|
it "raises an error if :pool isn't a pool" do
|
60
74
|
assert_raises(RuntimeError, 'pool must be an instance of ConnectionPool') do
|
61
75
|
ActiveSupport::Cache::RedisStore.new(pool: 'poolio')
|
@@ -204,8 +218,12 @@ describe ActiveSupport::Cache::RedisStore do
|
|
204
218
|
|
205
219
|
it "deletes matched data" do
|
206
220
|
with_store_management do |store|
|
221
|
+
store.write "rabbit2", @white_rabbit
|
222
|
+
store.write "rub-a-dub", "Flora de Cana"
|
207
223
|
store.delete_matched "rabb*"
|
208
224
|
store.read("rabbit").must_be_nil
|
225
|
+
store.read("rabbit2").must_be_nil
|
226
|
+
store.exist?("rub-a-dub").must_equal(true)
|
209
227
|
end
|
210
228
|
end
|
211
229
|
|
@@ -261,7 +279,7 @@ describe ActiveSupport::Cache::RedisStore do
|
|
261
279
|
store.read("raw-counter", :raw => true).to_i.must_equal(3)
|
262
280
|
end
|
263
281
|
end
|
264
|
-
|
282
|
+
|
265
283
|
it "decrements a raw key" do
|
266
284
|
with_store_management do |store|
|
267
285
|
assert store.write("raw-counter", 3, :raw => true)
|
@@ -333,6 +351,43 @@ describe ActiveSupport::Cache::RedisStore do
|
|
333
351
|
end
|
334
352
|
end
|
335
353
|
|
354
|
+
describe "race_condition_ttl on fetch" do
|
355
|
+
it "persist entry for longer than given ttl" do
|
356
|
+
options = { force: true, expires_in: 1.second, race_condition_ttl: 2.seconds }
|
357
|
+
@store.fetch("rabbit", options) { @rabbit }
|
358
|
+
sleep 1.1
|
359
|
+
@store.delete("rabbit").must_equal(1)
|
360
|
+
end
|
361
|
+
|
362
|
+
it "limits stampede time to read-write duration" do
|
363
|
+
first_rabbit = second_rabbit = nil
|
364
|
+
options = { force: true, expires_in: 1.second, race_condition_ttl: 2.seconds }
|
365
|
+
@store.fetch("rabbit", options) { @rabbit }
|
366
|
+
sleep 1
|
367
|
+
|
368
|
+
th1 = Thread.new do
|
369
|
+
first_rabbit = @store.fetch("rabbit", race_condition_ttl: 2) do
|
370
|
+
sleep 1
|
371
|
+
@white_rabbit
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
sleep 0.1
|
376
|
+
|
377
|
+
th2 = Thread.new do
|
378
|
+
second_rabbit = @store.fetch("rabbit") { @white_rabbit }
|
379
|
+
end
|
380
|
+
|
381
|
+
th1.join
|
382
|
+
th2.join
|
383
|
+
|
384
|
+
first_rabbit.must_equal(@white_rabbit)
|
385
|
+
second_rabbit.must_equal(@rabbit)
|
386
|
+
|
387
|
+
@store.fetch("rabbit").must_equal(@white_rabbit)
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
336
391
|
it "reads multiple keys" do
|
337
392
|
@store.write "irish whisky", "Jameson"
|
338
393
|
result = @store.read_multi "rabbit", "irish whisky"
|
@@ -421,6 +476,22 @@ describe ActiveSupport::Cache::RedisStore do
|
|
421
476
|
end
|
422
477
|
end
|
423
478
|
|
479
|
+
describe "fetch_multi nested keys" do
|
480
|
+
it "reads existing keys and fills in anything missing" do
|
481
|
+
@store.write ["bourbon", "bourbon-extended"], "makers"
|
482
|
+
|
483
|
+
bourbon_key = ["bourbon", "bourbon-extended"]
|
484
|
+
rye_key = ["rye", "rye-extended"]
|
485
|
+
|
486
|
+
result = @store.fetch_multi(bourbon_key, rye_key) do |key|
|
487
|
+
"#{key}-was-missing"
|
488
|
+
end
|
489
|
+
|
490
|
+
result.must_equal({ bourbon_key => "makers", rye_key => "#{rye_key}-was-missing" })
|
491
|
+
@store.read(rye_key).must_equal("#{rye_key}-was-missing")
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
424
495
|
describe "notifications" do
|
425
496
|
it "notifies on #fetch" do
|
426
497
|
with_notifications do
|
@@ -610,4 +681,3 @@ describe ActiveSupport::Cache::RedisStore do
|
|
610
681
|
ActiveSupport::VERSION::MAJOR == 4 && ActiveSupport::VERSION::MINOR < 2
|
611
682
|
end
|
612
683
|
end
|
613
|
-
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-activesupport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.
|
4
|
+
version: 5.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
@@ -9,130 +9,130 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-02-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis-store
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 1.
|
20
|
+
version: 1.3.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ~>
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 1.
|
27
|
+
version: 1.3.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: activesupport
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- -
|
32
|
+
- - '>='
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '3'
|
35
|
-
- -
|
35
|
+
- - <
|
36
36
|
- !ruby/object:Gem::Version
|
37
37
|
version: '6'
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
requirements:
|
42
|
-
- -
|
42
|
+
- - '>='
|
43
43
|
- !ruby/object:Gem::Version
|
44
44
|
version: '3'
|
45
|
-
- -
|
45
|
+
- - <
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '6'
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: rake
|
50
50
|
requirement: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '10'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '10'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: bundler
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.3'
|
69
69
|
type: :development
|
70
70
|
prerelease: false
|
71
71
|
version_requirements: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ~>
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '1.3'
|
76
76
|
- !ruby/object:Gem::Dependency
|
77
77
|
name: mocha
|
78
78
|
requirement: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ~>
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 0.14.0
|
83
83
|
type: :development
|
84
84
|
prerelease: false
|
85
85
|
version_requirements: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ~>
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 0.14.0
|
90
90
|
- !ruby/object:Gem::Dependency
|
91
91
|
name: minitest
|
92
92
|
requirement: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '4.2'
|
97
|
-
- -
|
97
|
+
- - <
|
98
98
|
- !ruby/object:Gem::Version
|
99
99
|
version: '6'
|
100
100
|
type: :development
|
101
101
|
prerelease: false
|
102
102
|
version_requirements: !ruby/object:Gem::Requirement
|
103
103
|
requirements:
|
104
|
-
- -
|
104
|
+
- - '>='
|
105
105
|
- !ruby/object:Gem::Version
|
106
106
|
version: '4.2'
|
107
|
-
- -
|
107
|
+
- - <
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '6'
|
110
110
|
- !ruby/object:Gem::Dependency
|
111
111
|
name: connection_pool
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
114
|
-
- -
|
114
|
+
- - ~>
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
116
|
+
version: 2.2.0
|
117
117
|
type: :development
|
118
118
|
prerelease: false
|
119
119
|
version_requirements: !ruby/object:Gem::Requirement
|
120
120
|
requirements:
|
121
|
-
- -
|
121
|
+
- - ~>
|
122
122
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
123
|
+
version: 2.2.0
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: redis-store-testing
|
126
126
|
requirement: !ruby/object:Gem::Requirement
|
127
127
|
requirements:
|
128
|
-
- -
|
128
|
+
- - '>='
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
131
|
type: :development
|
132
132
|
prerelease: false
|
133
133
|
version_requirements: !ruby/object:Gem::Requirement
|
134
134
|
requirements:
|
135
|
-
- -
|
135
|
+
- - '>='
|
136
136
|
- !ruby/object:Gem::Version
|
137
137
|
version: '0'
|
138
138
|
description: Redis store for ActiveSupport
|
@@ -143,8 +143,8 @@ executables: []
|
|
143
143
|
extensions: []
|
144
144
|
extra_rdoc_files: []
|
145
145
|
files:
|
146
|
-
-
|
147
|
-
-
|
146
|
+
- .gitignore
|
147
|
+
- .travis.yml
|
148
148
|
- Gemfile
|
149
149
|
- MIT-LICENSE
|
150
150
|
- README.md
|
@@ -168,17 +168,17 @@ require_paths:
|
|
168
168
|
- lib
|
169
169
|
required_ruby_version: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
|
-
- -
|
171
|
+
- - '>='
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: '0'
|
174
174
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
175
|
requirements:
|
176
|
-
- -
|
176
|
+
- - '>='
|
177
177
|
- !ruby/object:Gem::Version
|
178
178
|
version: '0'
|
179
179
|
requirements: []
|
180
180
|
rubyforge_project: redis-activesupport
|
181
|
-
rubygems_version: 2.5.
|
181
|
+
rubygems_version: 2.5.2
|
182
182
|
signing_key:
|
183
183
|
specification_version: 4
|
184
184
|
summary: Redis store for ActiveSupport
|