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 +4 -4
- data/lib/redis/namespace/version.rb +1 -1
- data/lib/redis/namespace.rb +56 -8
- data/spec/deprecation_spec.rb +1 -1
- data/spec/redis_spec.rb +112 -0
- metadata +18 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c4fe7070f484a694ce41f97a0297e03d92cfa67746903d9fb74fa8439410494
|
4
|
+
data.tar.gz: 0cbfe04c2ca7b2d42ee603f0d67ba21c13cb938832cc99f89a2323842bb828a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec085b7e9fba5241cb2e2ad4ccf22d4282001a0ee37731e408a2135ea5e5439747441046cc6c48a2a372afe99f2fb6a67401867a20c8605e41206954eca72078
|
7
|
+
data.tar.gz: 0eff5c268bba88cb8bd5e0ab8115a404fed3180e82ebc4297ab8675da6c73e13b3bb943e77ec0392de4460683488589bbc227d95515aa5dc70cdb4236b58801d
|
data/lib/redis/namespace.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
579
|
+
wrapped_send(redis, command, &block)
|
534
580
|
else
|
535
|
-
|
536
|
-
|
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
|
data/spec/deprecation_spec.rb
CHANGED
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.
|
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-
|
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.
|
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.
|
133
|
+
rubygems_version: 3.3.15
|
121
134
|
signing_key:
|
122
135
|
specification_version: 4
|
123
136
|
summary: Namespaces Redis commands.
|