redis-namespace 1.9.0 → 1.11.0
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/lib/redis/namespace/version.rb +1 -1
- data/lib/redis/namespace.rb +62 -8
- data/spec/deprecation_spec.rb +1 -1
- data/spec/redis_spec.rb +130 -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: e003f4015162bfd465e79dd90e54b44ae46f0ec269118e10c08215d639166296
|
4
|
+
data.tar.gz: 16078b51e1bdab24977aa2b6fb7d0cd4761a7c41c340fcdacfb96dd32216c061
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb965b575fe3ec2f2f45b99a71839f569f647681939b16576c053ab3e25bf85db1db030941bbe6eaeecc624eeeaf8c0497c58c53c4231440896e9e116bc189e3
|
7
|
+
data.tar.gz: 07b2b2e20c4a152b3e3a4cfbf6abad773f335e098067a9b213e29dd80cfc4519f3d27c43febe6cf8261ffe95e73184e23a1b9ff557007eb7a8308e43a398bbb1
|
data/lib/redis/namespace.rb
CHANGED
@@ -72,6 +72,7 @@ class Redis
|
|
72
72
|
"exists?" => [ :all ],
|
73
73
|
"expire" => [ :first ],
|
74
74
|
"expireat" => [ :first ],
|
75
|
+
"expiretime" => [ :first ],
|
75
76
|
"eval" => [ :eval_style ],
|
76
77
|
"evalsha" => [ :eval_style ],
|
77
78
|
"get" => [ :first ],
|
@@ -122,6 +123,7 @@ class Redis
|
|
122
123
|
"persist" => [ :first ],
|
123
124
|
"pexpire" => [ :first ],
|
124
125
|
"pexpireat" => [ :first ],
|
126
|
+
"pexpiretime" => [ :first ],
|
125
127
|
"pfadd" => [ :first ],
|
126
128
|
"pfcount" => [ :all ],
|
127
129
|
"pfmerge" => [ :all ],
|
@@ -138,6 +140,7 @@ class Redis
|
|
138
140
|
"rpush" => [ :first ],
|
139
141
|
"rpushx" => [ :first ],
|
140
142
|
"sadd" => [ :first ],
|
143
|
+
"sadd?" => [ :first ],
|
141
144
|
"scard" => [ :first ],
|
142
145
|
"scan" => [ :scan_style, :second ],
|
143
146
|
"scan_each" => [ :scan_style, :all ],
|
@@ -158,6 +161,7 @@ class Redis
|
|
158
161
|
"spop" => [ :first ],
|
159
162
|
"srandmember" => [ :first ],
|
160
163
|
"srem" => [ :first ],
|
164
|
+
"srem?" => [ :first ],
|
161
165
|
"sscan" => [ :first ],
|
162
166
|
"sscan_each" => [ :first ],
|
163
167
|
"strlen" => [ :first ],
|
@@ -202,6 +206,7 @@ class Redis
|
|
202
206
|
HELPER_COMMANDS = {
|
203
207
|
"auth" => [],
|
204
208
|
"disconnect!" => [],
|
209
|
+
"close" => [],
|
205
210
|
"echo" => [],
|
206
211
|
"ping" => [],
|
207
212
|
"time" => [],
|
@@ -238,6 +243,16 @@ class Redis
|
|
238
243
|
# Support 1.8.7 by providing a namespaced reference to Enumerable::Enumerator
|
239
244
|
Enumerator = Enumerable::Enumerator unless defined?(::Enumerator)
|
240
245
|
|
246
|
+
# This is used by the Redis gem to determine whether or not to display that deprecation message.
|
247
|
+
@sadd_returns_boolean = true
|
248
|
+
|
249
|
+
# This is used by the Redis gem to determine whether or not to display that deprecation message.
|
250
|
+
@srem_returns_boolean = true
|
251
|
+
|
252
|
+
class << self
|
253
|
+
attr_accessor :sadd_returns_boolean, :srem_returns_boolean
|
254
|
+
end
|
255
|
+
|
241
256
|
attr_writer :namespace
|
242
257
|
attr_reader :redis
|
243
258
|
attr_accessor :warning
|
@@ -329,6 +344,32 @@ class Redis
|
|
329
344
|
end
|
330
345
|
ruby2_keywords(:eval) if respond_to?(:ruby2_keywords, true)
|
331
346
|
|
347
|
+
# This operation can run for a very long time if the namespace contains lots of keys!
|
348
|
+
# It should be used in tests, or when the namespace is small enough
|
349
|
+
# and you are sure you know what you are doing.
|
350
|
+
def clear
|
351
|
+
if warning?
|
352
|
+
warn("This operation can run for a very long time if the namespace contains lots of keys! " +
|
353
|
+
"It should be used in tests, or when the namespace is small enough " +
|
354
|
+
"and you are sure you know what you are doing.")
|
355
|
+
end
|
356
|
+
|
357
|
+
batch_size = 1000
|
358
|
+
|
359
|
+
if supports_scan?
|
360
|
+
cursor = "0"
|
361
|
+
begin
|
362
|
+
cursor, keys = scan(cursor, count: batch_size)
|
363
|
+
del(*keys) unless keys.empty?
|
364
|
+
end until cursor == "0"
|
365
|
+
else
|
366
|
+
all_keys = keys("*")
|
367
|
+
all_keys.each_slice(batch_size) do |keys|
|
368
|
+
del(*keys)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
332
373
|
ADMINISTRATIVE_COMMANDS.keys.each do |command|
|
333
374
|
define_method(command) do |*args, &block|
|
334
375
|
raise NoMethodError if deprecations?
|
@@ -371,7 +412,8 @@ class Redis
|
|
371
412
|
"passthrough has been deprecated and will be removed in " +
|
372
413
|
"redis-namespace 2.0 (at #{call_site})")
|
373
414
|
end
|
374
|
-
|
415
|
+
|
416
|
+
wrapped_send(@redis, command, args, &block)
|
375
417
|
else
|
376
418
|
super
|
377
419
|
end
|
@@ -476,7 +518,7 @@ class Redis
|
|
476
518
|
end
|
477
519
|
|
478
520
|
# Dispatch the command to Redis and store the result.
|
479
|
-
result = @redis
|
521
|
+
result = wrapped_send(@redis, command, args, &block)
|
480
522
|
|
481
523
|
# Don't try to remove namespace from a Redis::Future, you can't.
|
482
524
|
return result if result.is_a?(Redis::Future)
|
@@ -513,6 +555,16 @@ class Redis
|
|
513
555
|
end
|
514
556
|
end
|
515
557
|
|
558
|
+
def wrapped_send(redis_client, command, args = [], &block)
|
559
|
+
if redis_client.class.name == "ConnectionPool"
|
560
|
+
redis_client.with do |pool_connection|
|
561
|
+
pool_connection.send(command, *args, &block)
|
562
|
+
end
|
563
|
+
else
|
564
|
+
redis_client.send(command, *args, &block)
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
516
568
|
# Avoid modifying the caller's (pass-by-reference) arguments.
|
517
569
|
def clone_args(arg)
|
518
570
|
if arg.is_a?(Array)
|
@@ -530,13 +582,10 @@ class Redis
|
|
530
582
|
|
531
583
|
def namespaced_block(command, &block)
|
532
584
|
if block.arity == 0
|
533
|
-
redis
|
585
|
+
wrapped_send(redis, command, &block)
|
534
586
|
else
|
535
|
-
|
536
|
-
|
537
|
-
copy.redis = r
|
538
|
-
yield copy
|
539
|
-
end
|
587
|
+
outer_block = proc { |r| copy = dup; copy.redis = r; yield copy }
|
588
|
+
wrapped_send(redis, command, &outer_block)
|
540
589
|
end
|
541
590
|
end
|
542
591
|
|
@@ -582,5 +631,10 @@ class Redis
|
|
582
631
|
Enumerator.new(&block)
|
583
632
|
end
|
584
633
|
end
|
634
|
+
|
635
|
+
def supports_scan?
|
636
|
+
redis_version = @redis.info["redis_version"]
|
637
|
+
Gem::Version.new(redis_version) >= Gem::Version.new("2.8.0")
|
638
|
+
end
|
585
639
|
end
|
586
640
|
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,17 @@ 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
|
+
|
366
|
+
it "should remove members" do
|
367
|
+
@namespaced.sadd('foo', 1)
|
368
|
+
expect(@namespaced.srem?('foo', 1)).to eq(true)
|
369
|
+
expect(@namespaced.srem?('foo', 1)).to eq(false)
|
370
|
+
end
|
371
|
+
|
342
372
|
it "should add namespace to sort" do
|
343
373
|
@namespaced.sadd('foo', 1)
|
344
374
|
@namespaced.sadd('foo', 2)
|
@@ -376,6 +406,26 @@ describe "redis" do
|
|
376
406
|
expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
|
377
407
|
end
|
378
408
|
|
409
|
+
it "should utilize connection_pool while adding namepsace to multi blocks" do
|
410
|
+
memo = @namespaced
|
411
|
+
connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
|
412
|
+
@namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
|
413
|
+
|
414
|
+
expect(connection_pool).to receive(:with).and_call_original do |arg|
|
415
|
+
expect(arg).to be(an_instance_of(Redis))
|
416
|
+
end.at_least(:once)
|
417
|
+
|
418
|
+
@namespaced.mapped_hmset "foo", {"key" => "value"}
|
419
|
+
@namespaced.multi do |r|
|
420
|
+
r.del "foo"
|
421
|
+
r.mapped_hmset "foo", {"key1" => "value1"}
|
422
|
+
end
|
423
|
+
expect(@redis.get("foo")).to eq("bar")
|
424
|
+
expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
|
425
|
+
|
426
|
+
@namespaced = memo
|
427
|
+
end
|
428
|
+
|
379
429
|
it "should pass through multi commands without block" do
|
380
430
|
@namespaced.mapped_hmset "foo", {"key" => "value"}
|
381
431
|
|
@@ -387,6 +437,28 @@ describe "redis" do
|
|
387
437
|
expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
|
388
438
|
end
|
389
439
|
|
440
|
+
it "should utilize connection_pool while passing through multi commands without block" do
|
441
|
+
memo = @namespaced
|
442
|
+
connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
|
443
|
+
@namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
|
444
|
+
|
445
|
+
expect(connection_pool).to receive(:with).and_call_original do |arg|
|
446
|
+
expect(arg).to be(an_instance_of(Redis))
|
447
|
+
end.at_least(:once)
|
448
|
+
|
449
|
+
@namespaced.mapped_hmset "foo", {"key" => "value"}
|
450
|
+
|
451
|
+
@namespaced.multi
|
452
|
+
@namespaced.del "foo"
|
453
|
+
@namespaced.mapped_hmset "foo", {"key1" => "value1"}
|
454
|
+
@namespaced.exec
|
455
|
+
|
456
|
+
expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
|
457
|
+
expect(@redis.get("foo")).to eq("bar")
|
458
|
+
|
459
|
+
@namespaced = memo
|
460
|
+
end
|
461
|
+
|
390
462
|
it 'should return futures without attempting to remove namespaces' do
|
391
463
|
@namespaced.multi do
|
392
464
|
@future = @namespaced.keys('*')
|
@@ -403,6 +475,26 @@ describe "redis" do
|
|
403
475
|
expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
|
404
476
|
end
|
405
477
|
|
478
|
+
it "should utilize connection_pool while adding namespace to pipelined blocks" do
|
479
|
+
memo = @namespaced
|
480
|
+
connection_pool = ConnectionPool.new(size: 2, timeout: 2) { Redis.new db: 15 }
|
481
|
+
@namespaced = Redis::Namespace.new(:ns, redis: connection_pool)
|
482
|
+
|
483
|
+
expect(connection_pool).to receive(:with).and_call_original do |arg|
|
484
|
+
expect(arg).to be(an_instance_of(Redis))
|
485
|
+
end.at_least(:once)
|
486
|
+
|
487
|
+
@namespaced.mapped_hmset "foo", {"key" => "value"}
|
488
|
+
@namespaced.pipelined do |r|
|
489
|
+
r.del "foo"
|
490
|
+
r.mapped_hmset "foo", {"key1" => "value1"}
|
491
|
+
end
|
492
|
+
expect(@namespaced.hgetall("foo")).to eq({"key1" => "value1"})
|
493
|
+
expect(@redis.get("foo")).to eq("bar")
|
494
|
+
|
495
|
+
@namespaced = memo
|
496
|
+
end
|
497
|
+
|
406
498
|
it "should returned response array from pipelined block" do
|
407
499
|
@namespaced.mset "foo", "bar", "key", "value"
|
408
500
|
result = @namespaced.pipelined do |r|
|
@@ -574,6 +666,12 @@ describe "redis" do
|
|
574
666
|
expect(@redis.ttl("ns:foo")).to satisfy {|v| (0..1).include?(v) }
|
575
667
|
end
|
576
668
|
|
669
|
+
it "should namespace expiretime" do
|
670
|
+
@namespaced.set('mykey', 'Hello')
|
671
|
+
@namespaced.expireat('mykey', 2000000000)
|
672
|
+
expect(@namespaced.expiretime('mykey')).to eq(2000000000)
|
673
|
+
end
|
674
|
+
|
577
675
|
it "should namespace hincrbyfloat" do
|
578
676
|
@namespaced.hset('mykey', 'field', 10.50)
|
579
677
|
expect(@namespaced.hincrbyfloat('mykey', 'field', 0.1)).to eq(10.6)
|
@@ -606,6 +704,12 @@ describe "redis" do
|
|
606
704
|
expect(@namespaced.pexpire('mykey', 1555555555005)).to eq(true)
|
607
705
|
end
|
608
706
|
|
707
|
+
it "should namespace pexpiretime" do
|
708
|
+
@namespaced.set('mykey', 'Hello')
|
709
|
+
@namespaced.pexpireat('mykey', 2000000000000)
|
710
|
+
expect(@namespaced.pexpiretime('mykey')).to eq(2000000000000)
|
711
|
+
end
|
712
|
+
|
609
713
|
it "should namespace psetex" do
|
610
714
|
expect(@namespaced.psetex('mykey', 10000, 'Hello')).to eq('OK')
|
611
715
|
expect(@namespaced.get('mykey')).to eq('Hello')
|
@@ -967,4 +1071,30 @@ describe "redis" do
|
|
967
1071
|
expect(sub_sub_namespaced.full_namespace).to eql("ns:sub1:sub2")
|
968
1072
|
end
|
969
1073
|
end
|
1074
|
+
|
1075
|
+
describe :clear do
|
1076
|
+
it "warns with helpful output" do
|
1077
|
+
expect { @namespaced.clear }.to output(/can run for a very long time/).to_stderr
|
1078
|
+
end
|
1079
|
+
|
1080
|
+
it "should delete all the keys" do
|
1081
|
+
@redis.set("foo", "bar")
|
1082
|
+
@namespaced.mset("foo1", "bar", "foo2", "bar")
|
1083
|
+
capture_stderr { @namespaced.clear }
|
1084
|
+
|
1085
|
+
expect(@redis.keys).to eq ["foo"]
|
1086
|
+
expect(@namespaced.keys).to be_empty
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
it "should delete all the keys in older redis" do
|
1090
|
+
allow(@redis).to receive(:info).and_return({ "redis_version" => "2.7.0" })
|
1091
|
+
|
1092
|
+
@redis.set("foo", "bar")
|
1093
|
+
@namespaced.mset("foo1", "bar", "foo2", "bar")
|
1094
|
+
capture_stderr { @namespaced.clear }
|
1095
|
+
|
1096
|
+
expect(@redis.keys).to eq ["foo"]
|
1097
|
+
expect(@namespaced.keys).to be_empty
|
1098
|
+
end
|
1099
|
+
end
|
970
1100
|
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.11.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:
|
15
|
+
date: 2023-06-08 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.11.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
|
133
|
+
rubygems_version: 3.4.1
|
121
134
|
signing_key:
|
122
135
|
specification_version: 4
|
123
136
|
summary: Namespaces Redis commands.
|