redis 3.0.0 → 3.0.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.
@@ -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