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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 436164d1ef3ef82be09f9eb7b3987ad2cbbb4ed8
4
- data.tar.gz: 02c68a30e474b0908ac13b6c4360bffe95b24bcb
3
+ metadata.gz: f76cc8e43f05938df0720d314014293a6f1fca07
4
+ data.tar.gz: 9e1058563ccda4f656c8f124c615997c52d05291
5
5
  SHA512:
6
- metadata.gz: 2ba686e12401b4e55d3f481fa2364d5c83e6321226264e8be2896304e4128dc533037ca33a34e4254d19cac3403a58b446477d5862500c27e8d1e240f8c99381
7
- data.tar.gz: 9ecba7650fabe45b2fe0d353525e15ab6f3ac2e272c496799a420eb063657137eb17a19a7ae11520cd91c001ff5a5b148a3b126ef274e76e1f33518477c978e5
6
+ metadata.gz: ff1a913f4f8cdbba56665589c487f9def5e02f527b9fa20f06786aaabd0bd97abd4f3d2833639e55b892862fee72671e9aa6e967f9147de0fa380cf5b7e6cdad
7
+ data.tar.gz: 9edd85a05fd26962dae0a831f6ad1f74d165e6f3399f0e8d42135bb4394da96f7559faef00fa2bd6b9fbb12087fe04be57a08e892f3c8f99cbd6fe67bfebc3ef
data/.travis.yml CHANGED
@@ -11,8 +11,6 @@ rvm:
11
11
  - 2.2.4
12
12
  - 2.3.0
13
13
  - ruby-head
14
- - rbx-19mode
15
- - jruby-19mode
16
14
  - jruby-head
17
15
  services:
18
16
  - redis-server
data/Gemfile CHANGED
@@ -1,8 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
- if ::File.directory?(gem_path = '../redis-store')
5
- gem 'redis-store', '~> 1.2.0.pre', path: gem_path
6
- end
7
-
8
4
  gem 'i18n'
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
- [![Gem Version](https://badge.fury.io/rb/redis-activesupport.png)](http://badge.fury.io/rb/redis-activesupport) [![Build Status](https://secure.travis-ci.org/redis-store/redis-activesupport.png?branch=master)](http://travis-ci.org/jodosha/redis-activesupport?branch=master) [![Code Climate](https://codeclimate.com/github/jodosha/redis-store.png)](https://codeclimate.com/github/redis-store/redis-activesupport)
34
+ [![Gem Version](https://badge.fury.io/rb/redis-activesupport.png)](http://badge.fury.io/rb/redis-activesupport)
35
+ [![Build Status](https://secure.travis-ci.org/redis-store/redis-activesupport.png?branch=master)](http://travis-ci.org/redis-store/redis-activesupport?branch=master)
36
+ [![Code Climate](https://codeclimate.com/github/redis-store/redis-activesupport.png)](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 is O(N) over the
68
- # total number of keys in the database. Users of large Redis caches should
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
- !(keys = store.keys(matcher)).empty? && store.del(*keys)
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, (name, _)|
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 namespaced_key(key, options), amount}
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 namespaced_key(key, options), amount}
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 namespaced_key(key, options), ttl }
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
-
@@ -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.1'
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.2.0'
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', '~> 1.2.0'
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.1
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: 2016-07-06 00:00:00.000000000 Z
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.2.0
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.2.0
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: 1.2.0
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: 1.2.0
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
- - ".gitignore"
147
- - ".travis.yml"
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.1
181
+ rubygems_version: 2.5.2
182
182
  signing_key:
183
183
  specification_version: 4
184
184
  summary: Redis store for ActiveSupport