Skip to content

Commit 934edef

Browse files
committed
Merge pull request #396 from redis/dup2
Add ability to duplicate connections.
2 parents e94b465 + 4bb256d commit 934edef

File tree

5 files changed

+54
-3
lines changed

5 files changed

+54
-3
lines changed

lib/redis.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def self.current=(redis)
2727
include MonitorMixin
2828

2929
def initialize(options = {})
30+
@options = options.dup
3031
@original_client = @client = Client.new(options)
3132

3233
super() # Monitor#initialize
@@ -2422,6 +2423,10 @@ def inspect
24222423
"#<Redis client v#{Redis::VERSION} for #{id}>"
24232424
end
24242425

2426+
def dup
2427+
self.class.new(@options)
2428+
end
2429+
24252430
def method_missing(command, *args)
24262431
synchronize do |client|
24272432
client.call([command] + args)

lib/redis/distributed.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ def message
1616
attr_reader :ring
1717

1818
def initialize(node_configs, options = {})
19-
@tag = options.delete(:tag) || /^\{(.+?)\}/
20-
@ring = options.delete(:ring) || HashRing.new
21-
@default_options = options
19+
@tag = options[:tag] || /^\{(.+?)\}/
20+
@ring = options[:ring] || HashRing.new
21+
@node_configs = node_configs.dup
22+
@default_options = options.dup
2223
node_configs.each { |node_config| add_node(node_config) }
2324
@subscribed_node = nil
2425
end
@@ -807,6 +808,10 @@ def inspect
807808
"#<Redis client v#{Redis::VERSION} for #{nodes.map(&:id).join(', ')}>"
808809
end
809810

811+
def dup
812+
self.class.new(@node_configs, @default_options)
813+
end
814+
810815
protected
811816

812817
def on_each_node(command, *args)

test/distributed_internals_test.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,33 @@ def test_override_id
3838
assert_equal redis.nodes.last.client.id, "test1"
3939
assert_equal "#<Redis client v#{Redis::VERSION} for #{redis.nodes.map(&:id).join(', ')}>", redis.inspect
4040
end
41+
42+
def test_can_be_duped_to_create_a_new_connection
43+
redis = Redis::Distributed.new(NODES)
44+
45+
clients = redis.info[0]["connected_clients"].to_i
46+
47+
r2 = redis.dup
48+
r2.ping
49+
50+
assert_equal clients + 1, redis.info[0]["connected_clients"].to_i
51+
end
52+
53+
def test_keeps_options_after_dup
54+
r1 = Redis::Distributed.new(NODES, :tag => /^(\w+):/)
55+
56+
assert_raise(Redis::Distributed::CannotDistribute) do
57+
r1.sinter("foo", "bar")
58+
end
59+
60+
assert_equal [], r1.sinter("baz:foo", "baz:bar")
61+
62+
r2 = r1.dup
63+
64+
assert_raise(Redis::Distributed::CannotDistribute) do
65+
r2.sinter("foo", "bar")
66+
end
67+
68+
assert_equal [], r2.sinter("baz:foo", "baz:bar")
69+
end
4170
end

test/helper.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ module Generic
141141
def setup
142142
@log = StringIO.new
143143
@redis = init _new_client
144+
145+
# Run GC to make sure orphaned connections are closed.
146+
GC.start
144147
end
145148

146149
def teardown

test/internals_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,4 +342,13 @@ def test_does_not_change_self_client_options
342342
assert_equal 1, redis.client.options[:db]
343343
assert_equal "foo", redis.client.options[:scheme]
344344
end
345+
346+
def test_can_be_duped_to_create_a_new_connection
347+
clients = r.info["connected_clients"].to_i
348+
349+
r2 = r.dup
350+
r2.ping
351+
352+
assert_equal clients + 1, r.info["connected_clients"].to_i
353+
end
345354
end

0 commit comments

Comments
 (0)