redis 2.2.0 → 2.2.1

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.
@@ -21,8 +21,8 @@ class Redis
21
21
 
22
22
  def connect
23
23
  establish_connection
24
- call(:auth, @password) if @password
25
- call(:select, @db) if @db != 0
24
+ call [:auth, @password] if @password
25
+ call [:select, @db] if @db != 0
26
26
  self
27
27
  end
28
28
 
@@ -34,17 +34,40 @@ class Redis
34
34
  @path || "#{@host}:#{@port}"
35
35
  end
36
36
 
37
+ # Starting with 2.2.1, assume that this method is called with a single
38
+ # array argument. Check its size for backwards compat.
37
39
  def call(*args)
38
- reply = process(args) { read }
40
+ if args.first.is_a?(Array) && args.size == 1
41
+ command = args.first
42
+ else
43
+ command = args
44
+ end
45
+
46
+ reply = process([command]) { read }
39
47
  raise reply if reply.is_a?(RuntimeError)
40
48
  reply
41
49
  end
42
50
 
51
+ # Assume that this method is called with a single array argument. No
52
+ # backwards compat here, since it was introduced in 2.2.2.
53
+ def call_without_reply(command)
54
+ process([command])
55
+ nil
56
+ end
57
+
58
+ # Starting with 2.2.1, assume that this method is called with a single
59
+ # array argument. Check its size for backwards compat.
43
60
  def call_loop(*args)
61
+ if args.first.is_a?(Array) && args.size == 1
62
+ command = args.first
63
+ else
64
+ command = args
65
+ end
66
+
44
67
  error = nil
45
68
 
46
69
  result = without_socket_timeout do
47
- process(args) do
70
+ process([command]) do
48
71
  loop do
49
72
  reply = read
50
73
  if reply.is_a?(RuntimeError)
@@ -74,7 +97,7 @@ class Redis
74
97
  # read, retrying would re-execute the entire pipeline, thus re-issueing
75
98
  # already succesfully executed commands. To circumvent this, don't retry
76
99
  # after the first reply has been read succesfully.
77
- first = process(*commands) { read }
100
+ first = process(commands) { read }
78
101
  error = first if first.is_a?(RuntimeError)
79
102
 
80
103
  begin
@@ -109,7 +132,7 @@ class Redis
109
132
  retry
110
133
  end
111
134
 
112
- def process(*commands)
135
+ def process(commands)
113
136
  logging(commands) do
114
137
  ensure_connected do
115
138
  commands.each do |command|
@@ -4,7 +4,7 @@ class Redis
4
4
 
5
5
  COMMAND_DELIMITER = "\r\n"
6
6
 
7
- def build_command(*args)
7
+ def build_command(args)
8
8
  command = []
9
9
  command << "*#{args.size}"
10
10
 
@@ -16,7 +16,7 @@ class Redis
16
16
 
17
17
  # Trailing delimiter
18
18
  command << ""
19
- command
19
+ command.join(COMMAND_DELIMITER)
20
20
  end
21
21
 
22
22
  protected
@@ -55,7 +55,7 @@ class Redis
55
55
  end
56
56
 
57
57
  def write(command)
58
- @sock.syswrite(build_command(*command).join(COMMAND_DELIMITER))
58
+ @sock.write(build_command(command))
59
59
  end
60
60
 
61
61
  def read
@@ -116,7 +116,11 @@ class Redis
116
116
  end
117
117
 
118
118
  rescue LoadError
119
- warn "WARNING: using the built-in Timeout class which is known to have issues when used for opening connections. Install the SystemTimer gem if you want to make sure the Redis client will not hang." unless RUBY_VERSION >= "1.9" || RUBY_PLATFORM =~ /java/
119
+ if ! defined?(RUBY_ENGINE)
120
+ # MRI 1.8, all other interpreters define RUBY_ENGINE, JRuby and
121
+ # Rubinius should have no issues with timeout.
122
+ warn "WARNING: using the built-in Timeout class which is known to have issues when used for opening connections. Install the SystemTimer gem if you want to make sure the Redis client will not hang."
123
+ end
120
124
 
121
125
  require "timeout"
122
126
 
@@ -10,13 +10,19 @@ class Redis
10
10
 
11
11
  def post_init
12
12
  @req = nil
13
+ @connected = false
13
14
  @reader = ::Hiredis::Reader.new
14
15
  end
15
16
 
16
17
  def connection_completed
18
+ @connected = true
17
19
  succeed
18
20
  end
19
21
 
22
+ def connected?
23
+ @connected
24
+ end
25
+
20
26
  def receive_data(data)
21
27
  @reader.feed(data)
22
28
 
@@ -39,6 +45,7 @@ class Redis
39
45
  end
40
46
 
41
47
  def unbind
48
+ @connected = false
42
49
  if @req
43
50
  @req.fail [:error, Errno::ECONNRESET]
44
51
  @req = nil
@@ -53,12 +60,11 @@ class Redis
53
60
 
54
61
  def initialize
55
62
  @timeout = 5_000_000
56
- @state = :disconnected
57
63
  @connection = nil
58
64
  end
59
65
 
60
66
  def connected?
61
- @state == :connected
67
+ @connection && @connection.connected?
62
68
  end
63
69
 
64
70
  def timeout=(usecs)
@@ -79,13 +85,12 @@ class Redis
79
85
  end
80
86
 
81
87
  def disconnect
82
- @state = :disconnected
83
88
  @connection.close_connection
84
89
  @connection = nil
85
90
  end
86
91
 
87
92
  def write(command)
88
- @connection.send(build_command(*command).join(COMMAND_DELIMITER))
93
+ @connection.send(build_command(command))
89
94
  end
90
95
 
91
96
  def read
@@ -105,7 +110,6 @@ class Redis
105
110
  def setup_connect_callbacks(conn, f)
106
111
  conn.callback do
107
112
  @connection = conn
108
- @state = :connected
109
113
  f.resume conn
110
114
  end
111
115
 
@@ -637,8 +637,8 @@ class Redis
637
637
  end
638
638
 
639
639
  # Get information and statistics about the server.
640
- def info
641
- on_each_node :info
640
+ def info(cmd = nil)
641
+ on_each_node :info, cmd
642
642
  end
643
643
 
644
644
  # Listen for all requests received by the server in real time.
@@ -655,6 +655,13 @@ class Redis
655
655
  raise CannotDistribute, :pipelined
656
656
  end
657
657
 
658
+ def inspect
659
+ node_info = nodes.map do |node|
660
+ "#{node.id} (Redis v#{node.info['redis_version']})"
661
+ end
662
+ "#<Redis client v#{Redis::VERSION} connected to #{node_info.join(', ')}>"
663
+ end
664
+
658
665
  protected
659
666
 
660
667
  def on_each_node(command, *args)
@@ -6,8 +6,23 @@ class Redis
6
6
  @commands = []
7
7
  end
8
8
 
9
+ # Starting with 2.2.1, assume that this method is called with a single
10
+ # array argument. Check its size for backwards compat.
9
11
  def call(*args)
10
- @commands << args
12
+ if args.first.is_a?(Array) && args.size == 1
13
+ command = args.first
14
+ else
15
+ command = args
16
+ end
17
+
18
+ @commands << command
19
+ nil
20
+ end
21
+
22
+ # Assume that this method is called with a single array argument. No
23
+ # backwards compat here, since it was introduced in 2.2.2.
24
+ def call_without_reply(command)
25
+ @commands.push command
11
26
  nil
12
27
  end
13
28
 
@@ -4,8 +4,23 @@ class Redis
4
4
  @client = client
5
5
  end
6
6
 
7
+ # Starting with 2.2.1, assume that this method is called with a single
8
+ # array argument. Check its size for backwards compat.
7
9
  def call(*args)
8
- @client.process(args)
10
+ if args.first.is_a?(Array) && args.size == 1
11
+ command = args.first
12
+ else
13
+ command = args
14
+ end
15
+
16
+ @client.process([command])
17
+ end
18
+
19
+ # Assume that this method is called with a single array argument. No
20
+ # backwards compat here, since it was introduced in 2.2.2.
21
+ def call_without_reply(command)
22
+ @commands.push command
23
+ nil
9
24
  end
10
25
 
11
26
  def subscribe(*channels, &block)
@@ -17,11 +32,11 @@ class Redis
17
32
  end
18
33
 
19
34
  def unsubscribe(*channels)
20
- call(:unsubscribe, *channels)
35
+ call [:unsubscribe, *channels]
21
36
  end
22
37
 
23
38
  def punsubscribe(*channels)
24
- call(:punsubscribe, *channels)
39
+ call [:punsubscribe, *channels]
25
40
  end
26
41
 
27
42
  protected
@@ -30,7 +45,7 @@ class Redis
30
45
  sub = Subscription.new(&block)
31
46
 
32
47
  begin
33
- @client.call_loop(start, *channels) do |line|
48
+ @client.call_loop([start, *channels]) do |line|
34
49
  type, *rest = line
35
50
  sub.callbacks[type].call(*rest)
36
51
  break if type == stop && rest.last == 0
@@ -1,3 +1,3 @@
1
1
  class Redis
2
- VERSION = "2.2.0"
2
+ VERSION = "2.2.1"
3
3
  end
@@ -47,7 +47,8 @@ test "SHUTDOWN" do
47
47
  redis_mock(:shutdown => lambda { "+SHUTDOWN" }) do
48
48
  redis = Redis.new(OPTIONS.merge(:port => 6380))
49
49
 
50
- assert "SHUTDOWN" == redis.shutdown
50
+ # SHUTDOWN does not reply: test that it does not raise here.
51
+ assert nil == redis.shutdown
51
52
  end
52
53
  end
53
54
 
@@ -13,6 +13,15 @@ setup do
13
13
  end
14
14
 
15
15
  $TEST_PIPELINING = false
16
- $TEST_INSPECT = false
17
16
 
18
17
  load File.expand_path("./lint/internals.rb", File.dirname(__FILE__))
18
+
19
+ test "provides a meaningful inspect" do |r, _|
20
+ nodes = ["redis://localhost:6379/15", *NODES]
21
+ @r = Redis::Distributed.new nodes
22
+
23
+ node_info = nodes.map do |node|
24
+ "#{node} (Redis v#{@r.info.first["redis_version"]})"
25
+ end
26
+ assert "#<Redis client v#{Redis::VERSION} connected to #{node_info.join(', ')}>" == @r.inspect
27
+ end
@@ -16,6 +16,18 @@ test "INFO" do |r|
16
16
  end
17
17
  end
18
18
 
19
+ test "INFO COMMANDSTATS" do |r|
20
+ # Only available on Redis >= 2.3.0
21
+ next if r.info.first["redis_version"] < "2.3.0"
22
+
23
+ r.nodes.each { |n| n.config(:resetstat) }
24
+ r.ping # Executed on every node
25
+
26
+ r.info(:commandstats).each do |info|
27
+ assert "1" == info["ping"]["calls"]
28
+ end
29
+ end
30
+
19
31
  test "MONITOR" do |r|
20
32
  begin
21
33
  r.monitor
@@ -57,4 +57,3 @@ test "Unknown commands does not work by default" do |r|
57
57
  r.not_yet_implemented_command
58
58
  end
59
59
  end
60
-
@@ -43,7 +43,7 @@ end
43
43
 
44
44
  test_with_reconnection_check "Recover from raise in #call_loop" do |r|
45
45
  begin
46
- r.client.call_loop(:invalid_monitor) do
46
+ r.client.call_loop([:invalid_monitor]) do
47
47
  assert false # Should never be executed
48
48
  end
49
49
  rescue => ex
@@ -12,10 +12,13 @@ setup do
12
12
  end
13
13
 
14
14
  $TEST_PIPELINING = true
15
- $TEST_INSPECT = true
16
15
 
17
16
  load File.expand_path("./lint/internals.rb", File.dirname(__FILE__))
18
17
 
18
+ test "provides a meaningful inspect" do |r, _|
19
+ assert "#<Redis client v#{Redis::VERSION} connected to redis://127.0.0.1:6379/15 (Redis v#{r.info["redis_version"]})>" == r.inspect
20
+ end
21
+
19
22
  test "Redis.current" do
20
23
  Redis.current.set("foo", "bar")
21
24
 
@@ -27,10 +27,6 @@ test "Recovers from failed commands" do |r, _|
27
27
  end
28
28
  end
29
29
 
30
- test "provides a meaningful inspect" do |r, _|
31
- assert "#<Redis client v#{Redis::VERSION} connected to redis://127.0.0.1:6379/15 (Redis v#{r.info["redis_version"]})>" == r.inspect
32
- end if $TEST_INSPECT
33
-
34
30
  test "raises on protocol errors" do
35
31
  redis_mock(:ping => lambda { |*_| "foo" }) do
36
32
  assert_raise(Redis::ProtocolError) do
@@ -15,6 +15,17 @@ test "INFO" do |r|
15
15
  end
16
16
  end
17
17
 
18
+ test "INFO COMMANDSTATS" do |r|
19
+ # Only available on Redis >= 2.3.0
20
+ next if r.info["redis_version"] < "2.3.0"
21
+
22
+ r.config(:resetstat)
23
+ r.ping
24
+
25
+ result = r.info(:commandstats)
26
+ assert "1" == result["ping"]["calls"]
27
+ end
28
+
18
29
  test "MONITOR" do |r|
19
30
  log = []
20
31
 
@@ -52,6 +63,14 @@ test "DEBUG" do |r|
52
63
  assert r.debug(:object, "foo").kind_of?(String)
53
64
  end
54
65
 
66
+ test "OBJECT" do |r|
67
+ r.lpush "list", "value"
68
+
69
+ assert r.object(:refcount, "list") == 1
70
+ assert r.object(:encoding, "list") == "ziplist"
71
+ assert r.object(:idletime, "list").kind_of?(Fixnum)
72
+ end
73
+
55
74
  test "SYNC" do |r|
56
75
  replies = {:sync => lambda { "+OK" }}
57
76
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: redis
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 2.2.0
5
+ version: 2.2.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ezra Zygmuntowicz
@@ -18,7 +18,7 @@ autorequire: redis
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2011-03-29 00:00:00 -03:00
21
+ date: 2011-06-08 00:00:00 -03:00
22
22
  default_executable:
23
23
  dependencies: []
24
24
 
@@ -36,6 +36,7 @@ files:
36
36
  - LICENSE
37
37
  - README.md
38
38
  - Rakefile
39
+ - TODO.md
39
40
  - benchmarking/logging.rb
40
41
  - benchmarking/pipeline.rb
41
42
  - benchmarking/speed.rb
@@ -136,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
137
  requirements: []
137
138
 
138
139
  rubyforge_project: redis-rb
139
- rubygems_version: 1.5.2
140
+ rubygems_version: 1.6.2
140
141
  signing_key:
141
142
  specification_version: 3
142
143
  summary: Ruby client library for Redis, the key value storage server