redis-namespace 1.9.0 → 1.10.0

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
  SHA256:
3
- metadata.gz: 88bd88ddb249a9424c8bcc002b84f097a96b4de6450944bc66096e6524115431
4
- data.tar.gz: 1b9b4d59744b77a65ec523a77ea438de1f0923494a838c94a8c312893dce1fa6
3
+ metadata.gz: 8c4fe7070f484a694ce41f97a0297e03d92cfa67746903d9fb74fa8439410494
4
+ data.tar.gz: 0cbfe04c2ca7b2d42ee603f0d67ba21c13cb938832cc99f89a2323842bb828a3
5
5
  SHA512:
6
- metadata.gz: 2007d2f5396aec757c50d77de437dc01630b10de02eaeb852f7858233729476582036cf8214ba6e893f3e26b574c22169530a44bf9fb24c39fa2f2d5958e7ee5
7
- data.tar.gz: af47dc4b2ce8357f8751c99ed71d05dc213a75a8092a3d54f016cef36b327967445b915bfaed32565639b0b2c16dbd02ef0026fbabcbf07c8965d3bb42b04f16
6
+ metadata.gz: ec085b7e9fba5241cb2e2ad4ccf22d4282001a0ee37731e408a2135ea5e5439747441046cc6c48a2a372afe99f2fb6a67401867a20c8605e41206954eca72078
7
+ data.tar.gz: 0eff5c268bba88cb8bd5e0ab8115a404fed3180e82ebc4297ab8675da6c73e13b3bb943e77ec0392de4460683488589bbc227d95515aa5dc70cdb4236b58801d
@@ -2,6 +2,6 @@
2
2
 
3
3
  class Redis
4
4
  class Namespace
5
- VERSION = '1.9.0'
5
+ VERSION = '1.10.0'
6
6
  end
7
7
  end
@@ -138,6 +138,7 @@ class Redis
138
138
  "rpush" => [ :first ],
139
139
  "rpushx" => [ :first ],
140
140
  "sadd" => [ :first ],
141
+ "sadd?" => [ :first ],
141
142
  "scard" => [ :first ],
142
143
  "scan" => [ :scan_style, :second ],
143
144
  "scan_each" => [ :scan_style, :all ],
@@ -202,6 +203,7 @@ class Redis
202
203
  HELPER_COMMANDS = {
203
204
  "auth" => [],
204
205
  "disconnect!" => [],
206
+ "close" => [],
205
207
  "echo" => [],
206
208
  "ping" => [],
207
209
  "time" => [],
@@ -238,6 +240,13 @@ class Redis
238
240
  # Support 1.8.7 by providing a namespaced reference to Enumerable::Enumerator
239
241
  Enumerator = Enumerable::Enumerator unless defined?(::Enumerator)
240
242
 
243
+ # This is used by the Redis gem to determine whether or not to display that deprecation message.
244
+ @sadd_returns_boolean = true
245
+
246
+ class << self
247
+ attr_accessor :sadd_returns_boolean
248
+ end
249
+
241
250
  attr_writer :namespace
242
251
  attr_reader :redis
243
252
  attr_accessor :warning
@@ -329,6 +338,32 @@ class Redis
329
338
  end
330
339
  ruby2_keywords(:eval) if respond_to?(:ruby2_keywords, true)
331
340
 
341
+ # This operation can run for a very long time if the namespace contains lots of keys!
342
+ # It should be used in tests, or when the namespace is small enough
343
+ # and you are sure you know what you are doing.
344
+ def clear
345
+ if warning?
346
+ warn("This operation can run for a very long time if the namespace contains lots of keys! " +
347
+ "It should be used in tests, or when the namespace is small enough " +
348
+ "and you are sure you know what you are doing.")
349
+ end
350
+
351
+ batch_size = 1000
352
+
353
+ if supports_scan?
354
+ cursor = "0"
355
+ begin
356
+ cursor, keys = scan(cursor, count: batch_size)
357
+ del(*keys) unless keys.empty?
358
+ end until cursor == "0"
359
+ else
360
+ all_keys = keys("*")
361
+ all_keys.each_slice(batch_size) do |keys|
362
+ del(*keys)
363
+ end
364
+ end
365
+ end
366
+
332
367
  ADMINISTRATIVE_COMMANDS.keys.each do |command|
333
368
  define_method(command) do |*args, &block|
334
369
  raise NoMethodError if deprecations?
@@ -371,7 +406,8 @@ class Redis
371
406
  "passthrough has been deprecated and will be removed in " +
372
407
  "redis-namespace 2.0 (at #{call_site})")
373
408
  end
374
- @redis.send(command, *args, &block)
409
+
410
+ wrapped_send(@redis, command, args, &block)
375
411
  else
376
412
  super
377
413
  end
@@ -476,7 +512,7 @@ class Redis
476
512
  end
477
513
 
478
514
  # Dispatch the command to Redis and store the result.
479
- result = @redis.send(command, *args, &block)
515
+ result = wrapped_send(@redis, command, args, &block)
480
516
 
481
517
  # Don't try to remove namespace from a Redis::Future, you can't.
482
518
  return result if result.is_a?(Redis::Future)
@@ -513,6 +549,16 @@ class Redis
513
549
  end
514
550
  end
515
551
 
552
+ def wrapped_send(redis_client, command, args = [], &block)
553
+ if redis_client.class.name == "ConnectionPool"
554
+ redis_client.with do |pool_connection|
555
+ pool_connection.send(command, *args, &block)
556
+ end
557
+ else
558
+ redis_client.send(command, *args, &block)
559
+ end
560
+ end
561
+
516
562
  # Avoid modifying the caller's (pass-by-reference) arguments.
517
563
  def clone_args(arg)
518
564
  if arg.is_a?(Array)
@@ -530,13 +576,10 @@ class Redis
530
576
 
531
577
  def namespaced_block(command, &block)
532
578
  if block.arity == 0
533
- redis.send(command, &block)
579
+ wrapped_send(redis, command, &block)
534
580
  else
535
- redis.send(command) do |r|
536
- copy = dup
537
- copy.redis = r
538
- yield copy
539
- end
581
+ outer_block = proc { |r| copy = dup; copy.redis = r; yield copy }
582
+ wrapped_send(redis, command, &outer_block)
540
583
  end
541
584
  end
542
585
 
@@ -582,5 +625,10 @@ class Redis
582
625
  Enumerator.new(&block)
583
626
  end
584
627
  end
628
+
629
+ def supports_scan?
630
+ redis_version = @redis.info["redis_version"]
631
+ Gem::Version.new(redis_version) >= Gem::Version.new("2.8.0")
632
+ end
585
633
  end
586
634
  end
@@ -31,7 +31,7 @@ describe Redis::Namespace do
31
31
  end
32
32
 
33
33
  before(:each) do
34
- allow(redis).to receive(:unhandled) do |*args|
34
+ allow(redis).to receive(:unhandled) do |*args|
35
35
  "unhandled(#{args.inspect})"
36
36
  end
37
37
  allow(redis).to receive(:flushdb).and_return("OK")
data/spec/redis_spec.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require File.dirname(__FILE__) + '/spec_helper'
4
+ require 'connection_pool'
4
5
 
5
6
  describe "redis" do
6
7
  @redis_version = Gem::Version.new(Redis.new.info["redis_version"])
@@ -184,6 +185,24 @@ describe "redis" do
184
185
  expect(@namespaced.mapped_mget('foo', 'baz', 'bar')).to eq({'foo'=>'1000', 'bar'=>'2000', 'baz' => nil})
185
186
  end
186
187
 
188
+ it "should utilize connection_pool while using a namespace with mget" do
189
+ memo = @namespaced
190
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
191
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
192
+
193
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
194
+ expect(arg).to be(an_instance_of(Redis))
195
+ end.at_least(:once)
196
+
197
+ @namespaced.set('foo', 1000)
198
+ @namespaced.set('bar', 2000)
199
+ expect(@namespaced.mapped_mget('foo', 'bar')).to eq({ 'foo' => '1000', 'bar' => '2000' })
200
+ expect(@namespaced.mapped_mget('foo', 'baz', 'bar')).to eq({'foo'=>'1000', 'bar'=>'2000', 'baz' => nil})
201
+ @redis.get('foo').should eq('bar')
202
+
203
+ @namespaced = memo
204
+ end
205
+
187
206
  it "should be able to use a namespace with mset" do
188
207
  @namespaced.mset('foo', '1000', 'bar', '2000')
189
208
  expect(@namespaced.mapped_mget('foo', 'bar')).to eq({ 'foo' => '1000', 'bar' => '2000' })
@@ -339,6 +358,11 @@ describe "redis" do
339
358
  expect(values).to match_array(['banana', 'eggplant'])
340
359
  end
341
360
 
361
+ it "should add a new member" do
362
+ expect(@namespaced.sadd?('foo', 1)).to eq(true)
363
+ expect(@namespaced.sadd?('foo', 1)).to eq(false)
364
+ end
365
+
342
366
  it "should add namespace to sort" do
343
367
  @namespaced.sadd('foo', 1)
344
368
  @namespaced.sadd('foo', 2)
@@ -376,6 +400,26 @@ describe "redis" do
376
400
  expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
377
401
  end
378
402
 
403
+ it "should utilize connection_pool while adding namepsace to multi blocks" do
404
+ memo = @namespaced
405
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
406
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
407
+
408
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
409
+ expect(arg).to be(an_instance_of(Redis))
410
+ end.at_least(:once)
411
+
412
+ @namespaced.mapped_hmset "foo", {"key" => "value"}
413
+ @namespaced.multi do |r|
414
+ r.del "foo"
415
+ r.mapped_hmset "foo", {"key1" => "value1"}
416
+ end
417
+ expect(@redis.get("foo")).to eq("bar")
418
+ expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
419
+
420
+ @namespaced = memo
421
+ end
422
+
379
423
  it "should pass through multi commands without block" do
380
424
  @namespaced.mapped_hmset "foo", {"key" => "value"}
381
425
 
@@ -387,6 +431,28 @@ describe "redis" do
387
431
  expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
388
432
  end
389
433
 
434
+ it "should utilize connection_pool while passing through multi commands without block" do
435
+ memo = @namespaced
436
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
437
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
438
+
439
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
440
+ expect(arg).to be(an_instance_of(Redis))
441
+ end.at_least(:once)
442
+
443
+ @namespaced.mapped_hmset "foo", {"key" => "value"}
444
+
445
+ @namespaced.multi
446
+ @namespaced.del "foo"
447
+ @namespaced.mapped_hmset "foo", {"key1" => "value1"}
448
+ @namespaced.exec
449
+
450
+ expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
451
+ expect(@redis.get("foo")).to eq("bar")
452
+
453
+ @namespaced = memo
454
+ end
455
+
390
456
  it 'should return futures without attempting to remove namespaces' do
391
457
  @namespaced.multi do
392
458
  @future = @namespaced.keys('*')
@@ -403,6 +469,26 @@ describe "redis" do
403
469
  expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
404
470
  end
405
471
 
472
+ it "should utilize connection_pool while adding namespace to pipelined blocks" do
473
+ memo = @namespaced
474
+ connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
475
+ @namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
476
+
477
+ expect(connection_pool).to receive(:with).and_call_original do |arg|
478
+ expect(arg).to be(an_instance_of(Redis))
479
+ end.at_least(:once)
480
+
481
+ @namespaced.mapped_hmset "foo", {"key" => "value"}
482
+ @namespaced.pipelined do |r|
483
+ r.del "foo"
484
+ r.mapped_hmset "foo", {"key1" => "value1"}
485
+ end
486
+ expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
487
+ expect(@redis.get("foo")).to eq("bar")
488
+
489
+ @namespaced = memo
490
+ end
491
+
406
492
  it "should returned response array from pipelined block" do
407
493
  @namespaced.mset "foo", "bar", "key", "value"
408
494
  result = @namespaced.pipelined do |r|
@@ -967,4 +1053,30 @@ describe "redis" do
967
1053
  expect(sub_sub_namespaced.full_namespace).to eql("ns:sub1:sub2")
968
1054
  end
969
1055
  end
1056
+
1057
+ describe :clear do
1058
+ it "warns with helpful output" do
1059
+ expect { @namespaced.clear }.to output(/can run for a very long time/).to_stderr
1060
+ end
1061
+
1062
+ it "should delete all the keys" do
1063
+ @redis.set("foo", "bar")
1064
+ @namespaced.mset("foo1", "bar", "foo2", "bar")
1065
+ capture_stderr { @namespaced.clear }
1066
+
1067
+ expect(@redis.keys).to eq ["foo"]
1068
+ expect(@namespaced.keys).to be_empty
1069
+ end
1070
+
1071
+ it "should delete all the keys in older redis" do
1072
+ allow(@redis).to receive(:info).and_return({ "redis_version" => "2.7.0" })
1073
+
1074
+ @redis.set("foo", "bar")
1075
+ @namespaced.mset("foo1", "bar", "foo2", "bar")
1076
+ capture_stderr { @namespaced.clear }
1077
+
1078
+ expect(@redis.keys).to eq ["foo"]
1079
+ expect(@namespaced.keys).to be_empty
1080
+ end
1081
+ end
970
1082
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-namespace
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2022-08-13 00:00:00.000000000 Z
15
+ date: 2022-12-20 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: redis
@@ -70,6 +70,20 @@ dependencies:
70
70
  - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: '0'
73
+ - !ruby/object:Gem::Dependency
74
+ name: connection_pool
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
73
87
  description: |
74
88
  Adds a Redis::Namespace class which can be used to namespace calls
75
89
  to Redis. This is useful when using a single instance of Redis with
@@ -99,8 +113,7 @@ licenses:
99
113
  metadata:
100
114
  bug_tracker_uri: https://github.com/resque/redis-namespace/issues
101
115
  changelog_uri: https://github.com/resque/redis-namespace/blob/master/CHANGELOG.md
102
- documentation_uri: https://www.rubydoc.info/gems/redis-namespace/1.9.0
103
- source_code_uri: https://github.com/resque/redis-namespace/tree/v1.9.0
116
+ documentation_uri: https://www.rubydoc.info/gems/redis-namespace/1.10.0
104
117
  rubygems_mfa_required: 'true'
105
118
  post_install_message:
106
119
  rdoc_options: []
@@ -117,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
130
  - !ruby/object:Gem::Version
118
131
  version: '0'
119
132
  requirements: []
120
- rubygems_version: 3.1.6
133
+ rubygems_version: 3.3.15
121
134
  signing_key:
122
135
  specification_version: 4
123
136
  summary: Namespaces Redis commands.