redis-activesupport 5.0.1 → 5.0.2

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