Skip to content

Commit 8146e59

Browse files
committed
Merge branch 'master' into ipv6
Conflicts: test/internals_test.rb
2 parents df41577 + 900dbea commit 8146e59

10 files changed

+70
-9
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# (unreleased)
2+
3+
* Added method `Redis#dup` to duplicate a Redis connection.
4+
15
# 3.0.6
26

37
* Added support for `SCAN` and variants.

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,19 @@ listening on `localhost`, port 6379. If you need to connect to a remote
3838
server or a different port, try:
3939

4040
```ruby
41-
redis = Redis.new(:host => "10.0.1.1", :port => 6380)
41+
redis = Redis.new(:host => "10.0.1.1", :port => 6380, :db => 15)
4242
```
4343

44+
You can also specify connection options as an URL:
45+
46+
```ruby
47+
redis = Redis.new(:url => "redis://:[email protected]:6380/15")
48+
```
49+
50+
By default, the client will try to read the `REDIS_URL` environment variable
51+
and use that as URL to connect to. The above statement is therefore equivalent
52+
to setting this environment variable and calling `Redis.new` without arguments.
53+
4454
To connect to Redis listening on a Unix socket, try:
4555

4656
```ruby

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)

lib/redis/pipeline.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def finish(replies)
7878
# EXEC command failed.
7979
raise exec if exec.is_a?(CommandError)
8080

81-
if exec.size < futures.size - 2
81+
if exec.size < futures.size
8282
# Some command wasn't recognized by Redis.
8383
raise replies.detect { |r| r.is_a?(CommandError) }
8484
end

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
@@ -398,4 +398,13 @@ def test_connect_ipv6
398398
end
399399
end
400400
end
401+
402+
def test_can_be_duped_to_create_a_new_connection
403+
clients = r.info["connected_clients"].to_i
404+
405+
r2 = r.dup
406+
r2.ping
407+
408+
assert_equal clients + 1, r.info["connected_clients"].to_i
409+
end
401410
end

test/pipelining_commands_test.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ def test_assignment_of_results_inside_the_block_with_errors
9393
r.pipelined do
9494
r.doesnt_exist
9595
@first = r.sadd("foo", 1)
96-
r.doesnt_exist
9796
@second = r.sadd("foo", 1)
98-
r.doesnt_exist
9997
end
10098
end
10199

test/transactions_test.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@ def test_assignment_inside_multi_exec_block_with_immediate_command_errors
6767
r.multi do |m|
6868
m.doesnt_exist
6969
@first = m.sadd("foo", 1)
70-
m.doesnt_exist
7170
@second = m.sadd("foo", 1)
72-
m.doesnt_exist
7371
end
7472
end
7573

0 commit comments

Comments
 (0)