redis 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ # 3.0.1
2
+
3
+ * Fix reconnect logic not kicking in on a write error.
4
+
5
+ See 427dbd52928af452f35aa0a57b621bee56cdcb18 and #238.
6
+
1
7
  # 3.0.0
2
8
 
3
9
  ### Upgrading from 2.x to 3.0
@@ -1728,7 +1728,7 @@ class Redis
1728
1728
  # Set one or more hash values.
1729
1729
  #
1730
1730
  # @example
1731
- # redis.hmset("hash", { "f1" => "v1", "f2" => "v2" })
1731
+ # redis.mapped_hmset("hash", { "f1" => "v1", "f2" => "v2" })
1732
1732
  # # => "OK"
1733
1733
  #
1734
1734
  # @param [String] key
@@ -171,7 +171,7 @@ class Redis
171
171
  command[0] = command_map[command.first]
172
172
  end
173
173
 
174
- connection.write(command)
174
+ write(command)
175
175
  end
176
176
 
177
177
  yield if block_given?
@@ -1,3 +1,3 @@
1
1
  class Redis
2
- VERSION = "3.0.0"
2
+ VERSION = "3.0.1"
3
3
  end
@@ -7,9 +7,22 @@ class TestDistributedRemoteServerControlCommands < Test::Unit::TestCase
7
7
  include Helper::Distributed
8
8
 
9
9
  def test_info
10
- %w(last_save_time redis_version total_connections_received connected_clients total_commands_processed connected_slaves uptime_in_seconds used_memory uptime_in_days changes_since_last_save).each do |x|
11
- r.info.each do |info|
12
- assert info.keys.include?(x)
10
+ keys = [
11
+ "redis_version",
12
+ "uptime_in_seconds",
13
+ "uptime_in_days",
14
+ "connected_clients",
15
+ "used_memory",
16
+ "total_connections_received",
17
+ "total_commands_processed",
18
+ ]
19
+
20
+ info = r.info
21
+
22
+ info.each do |info|
23
+ keys.each do |k|
24
+ msg = "expected #info to include #{k}"
25
+ assert info.keys.include?(k), msg
13
26
  end
14
27
  end
15
28
  end
@@ -143,6 +143,12 @@ module Helper
143
143
  yield _new_client(options.merge(:port => port))
144
144
  end
145
145
  end
146
+
147
+ def redis_mock_with_handler(handler, options = {}, &blk)
148
+ RedisMock.start_with_handler(handler) do |port|
149
+ yield _new_client(options.merge(:port => port))
150
+ end
151
+ end
146
152
  end
147
153
 
148
154
  module Client
@@ -191,6 +191,75 @@ class TestInternals < Test::Unit::TestCase
191
191
  end
192
192
  end
193
193
 
194
+ def close_on_connection(seq)
195
+ $n = 0
196
+
197
+ read_command = lambda do |session|
198
+ Array.new(session.gets[1..-3].to_i) do
199
+ bytes = session.gets[1..-3].to_i
200
+ arg = session.read(bytes)
201
+ session.read(2) # Discard \r\n
202
+ arg
203
+ end
204
+ end
205
+
206
+ handler = lambda do |session|
207
+ n = $n
208
+ $n += 1
209
+
210
+ select = read_command.call(session)
211
+ if select[0].downcase == "select"
212
+ session.write("+OK\r\n")
213
+ else
214
+ raise "Expected SELECT"
215
+ end
216
+
217
+ if !seq.include?(n)
218
+ while read_command.call(session)
219
+ session.write("+#{n}\r\n")
220
+ end
221
+ end
222
+ end
223
+
224
+ redis_mock_with_handler(handler) do |redis|
225
+ yield(redis)
226
+ end
227
+ end
228
+
229
+ def test_retry_on_write_error_by_default
230
+ close_on_connection([0]) do |redis|
231
+ assert_equal "1", redis.client.call(["x" * 128 * 1024])
232
+ end
233
+ end
234
+
235
+ def test_retry_on_write_error_when_wrapped_in_with_reconnect_true
236
+ close_on_connection([0]) do |redis|
237
+ redis.with_reconnect(true) do
238
+ assert_equal "1", redis.client.call(["x" * 128 * 1024])
239
+ end
240
+ end
241
+ end
242
+
243
+ def test_dont_retry_on_write_error_when_wrapped_in_with_reconnect_false
244
+ close_on_connection([0]) do |redis|
245
+ assert_raise Redis::ConnectionError do
246
+ redis.with_reconnect(false) do
247
+ redis.client.call(["x" * 128 * 1024])
248
+ end
249
+ end
250
+ end
251
+ end
252
+
253
+ def test_dont_retry_on_write_error_when_wrapped_in_without_reconnect
254
+ close_on_connection([0]) do |redis|
255
+ assert_raise Redis::ConnectionError do
256
+ redis.without_reconnect do
257
+ redis.client.call(["x" * 128 * 1024])
258
+ end
259
+ end
260
+ end
261
+ end
262
+
194
263
  def test_connecting_to_unix_domain_socket
195
264
  assert_nothing_raised do
196
265
  Redis.new(OPTIONS.merge(:path => "/tmp/redis.sock")).ping
@@ -7,8 +7,21 @@ class TestRemoteServerControlCommands < Test::Unit::TestCase
7
7
  include Helper::Client
8
8
 
9
9
  def test_info
10
- %w(last_save_time redis_version total_connections_received connected_clients total_commands_processed connected_slaves uptime_in_seconds used_memory uptime_in_days changes_since_last_save).each do |x|
11
- assert r.info.keys.include?(x)
10
+ keys = [
11
+ "redis_version",
12
+ "uptime_in_seconds",
13
+ "uptime_in_days",
14
+ "connected_clients",
15
+ "used_memory",
16
+ "total_connections_received",
17
+ "total_commands_processed",
18
+ ]
19
+
20
+ info = r.info
21
+
22
+ keys.each do |k|
23
+ msg = "expected #info to include #{k}"
24
+ assert info.keys.include?(k), msg
12
25
  end
13
26
  end
14
27
 
@@ -28,32 +28,9 @@ module RedisMock
28
28
  session = @server.accept
29
29
 
30
30
  begin
31
- while line = session.gets
32
- parts = Array.new(line[1..-3].to_i) do
33
- bytes = session.gets[1..-3].to_i
34
- argument = session.read(bytes)
35
- session.read(2) # Discard \r\n
36
- argument
37
- end
38
-
39
- response = yield(*parts)
40
-
41
- # Convert a nil response to :close
42
- response ||= :close
43
-
44
- if response == :exit
45
- session.shutdown(Socket::SHUT_RDWR)
46
- return # exit server body
47
- elsif response == :close
48
- session.shutdown(Socket::SHUT_RDWR)
49
- break # exit connection body
50
- else
51
- session.write(response)
52
- session.write("\r\n") unless response.end_with?("\r\n")
53
- end
54
- end
55
- rescue Errno::ECONNRESET
56
- # Ignore client closing the connection
31
+ return if yield(session) == :exit
32
+ ensure
33
+ session.close
57
34
  end
58
35
  end
59
36
  rescue => ex
@@ -68,20 +45,19 @@ module RedisMock
68
45
 
69
46
  # Starts a mock Redis server in a thread.
70
47
  #
71
- # The server will reply with a `+OK` to all commands, but you can
72
- # customize it by providing a hash. For example:
48
+ # The server will use the lambda handler passed as argument to handle
49
+ # connections. For example:
73
50
  #
74
- # RedisMock.start(:ping => lambda { "+PONG" }) do
75
- # assert_equal "PONG", Redis.new(:port => MOCK_PORT).ping
76
- # end
51
+ # handler = lambda { |session| session.close }
52
+ # RedisMock.start_with_handler(handler) do
53
+ # # Every connection will be closed immediately
54
+ # end
77
55
  #
78
- def self.start(commands = {})
56
+ def self.start_with_handler(blk)
79
57
  server = Server.new(MOCK_PORT)
80
58
 
81
59
  begin
82
- server.start do |command, *args|
83
- (commands[command.to_sym] || lambda { |*_| "+OK" }).call(*args)
84
- end
60
+ server.start(&blk)
85
61
 
86
62
  yield(MOCK_PORT)
87
63
 
@@ -89,4 +65,46 @@ module RedisMock
89
65
  server.shutdown
90
66
  end
91
67
  end
68
+
69
+ # Starts a mock Redis server in a thread.
70
+ #
71
+ # The server will reply with a `+OK` to all commands, but you can
72
+ # customize it by providing a hash. For example:
73
+ #
74
+ # RedisMock.start(:ping => lambda { "+PONG" }) do
75
+ # assert_equal "PONG", Redis.new(:port => MOCK_PORT).ping
76
+ # end
77
+ #
78
+ def self.start(commands = {}, &blk)
79
+ handler = lambda do |session|
80
+ while line = session.gets
81
+ argv = Array.new(line[1..-3].to_i) do
82
+ bytes = session.gets[1..-3].to_i
83
+ arg = session.read(bytes)
84
+ session.read(2) # Discard \r\n
85
+ arg
86
+ end
87
+
88
+ command = argv.shift
89
+ blk = commands[command.to_sym]
90
+ blk ||= lambda { |*_| "+OK" }
91
+
92
+ response = blk.call(*argv)
93
+
94
+ # Convert a nil response to :close
95
+ response ||= :close
96
+
97
+ if response == :exit
98
+ break :exit
99
+ elsif response == :close
100
+ break :close
101
+ else
102
+ session.write(response)
103
+ session.write("\r\n") unless response.end_with?("\r\n")
104
+ end
105
+ end
106
+ end
107
+
108
+ start_with_handler(handler, &blk)
109
+ end
92
110
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -17,7 +17,7 @@ authors:
17
17
  autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
- date: 2012-05-23 00:00:00.000000000 Z
20
+ date: 2012-06-02 00:00:00.000000000 Z
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
23
  name: rake