File tree Expand file tree Collapse file tree 4 files changed +37
-2
lines changed Expand file tree Collapse file tree 4 files changed +37
-2
lines changed Original file line number Diff line number Diff line change @@ -13,6 +13,7 @@ class Client
13
13
:path => nil ,
14
14
:timeout => 5.0 ,
15
15
:connect_timeout => 5.0 ,
16
+ :write_timeout => nil ,
16
17
:password => nil ,
17
18
:db => 0 ,
18
19
:driver => nil ,
@@ -433,6 +434,8 @@ def _parse_options(options)
433
434
options [ :timeout ]
434
435
end
435
436
437
+ options [ :write_timeout ] = options [ :write_timeout ] ? options [ :write_timeout ] . to_f : options [ :timeout ]
438
+
436
439
options [ :db ] = options [ :db ] . to_i
437
440
options [ :driver ] = _parse_driver ( options [ :driver ] ) || Connection . drivers . last
438
441
Original file line number Diff line number Diff line change 2
2
require "redis/connection/command_helper"
3
3
require "redis/errors"
4
4
require "socket"
5
+ require "timeout"
5
6
6
7
class Redis
7
8
module Connection
@@ -12,7 +13,7 @@ module SocketMixin
12
13
def initialize ( *args )
13
14
super ( *args )
14
15
15
- @timeout = nil
16
+ @timeout = @write_timeout = nil
16
17
@buffer = ""
17
18
end
18
19
@@ -24,6 +25,14 @@ def timeout=(timeout)
24
25
end
25
26
end
26
27
28
+ def write_timeout = ( timeout )
29
+ if timeout && timeout > 0
30
+ @write_timeout = timeout
31
+ else
32
+ @write_timeout = nil
33
+ end
34
+ end
35
+
27
36
def read ( nbytes )
28
37
result = @buffer . slice! ( 0 , nbytes )
29
38
@@ -59,6 +68,11 @@ def _read_from_socket(nbytes)
59
68
rescue EOFError
60
69
raise Errno ::ECONNRESET
61
70
end
71
+
72
+ # UNIXSocket and TCPSocket don't support write timeouts
73
+ def write ( *args )
74
+ Timeout . timeout ( @write_timeout , TimeoutError ) { super }
75
+ end
62
76
end
63
77
64
78
if defined? ( RUBY_ENGINE ) && RUBY_ENGINE == "jruby"
@@ -213,6 +227,7 @@ def self.connect(config)
213
227
214
228
instance = new ( sock )
215
229
instance . timeout = config [ :timeout ]
230
+ instance . write_timeout = config [ :write_timeout ]
216
231
instance . set_tcp_keepalive config [ :tcp_keepalive ]
217
232
instance
218
233
end
@@ -265,6 +280,10 @@ def timeout=(timeout)
265
280
end
266
281
end
267
282
283
+ def write_timeout = ( timeout )
284
+ @sock . write_timeout = timeout
285
+ end
286
+
268
287
def write ( command )
269
288
@sock . write ( build_command ( command ) )
270
289
end
Original file line number Diff line number Diff line change @@ -160,6 +160,19 @@ def test_connection_timeout
160
160
assert ( Time . now - start_time ) <= opts [ :timeout ]
161
161
end
162
162
163
+ driver ( :ruby ) do
164
+ def test_write_timeout
165
+ TCPServer . new ( "127.0.0.1" , 6383 )
166
+
167
+ assert_raise ( Redis ::TimeoutError ) do
168
+ Timeout . timeout ( 1 ) do
169
+ redis = Redis . new ( :port => 6383 , :timeout => 5 , :write_timeout => 0.2 )
170
+ redis . set ( "foo" , "1" * 1048576 )
171
+ end
172
+ end
173
+ end
174
+ end
175
+
163
176
def close_on_ping ( seq , options = { } )
164
177
$request = 0
165
178
Original file line number Diff line number Diff line change @@ -35,7 +35,7 @@ def mock(options = {}, &blk)
35
35
:brpoplpush => lambda do |*args |
36
36
sleep options [ :delay ] if options . has_key? ( :delay )
37
37
to_protocol ( args . last )
38
- end ,
38
+ end
39
39
}
40
40
41
41
redis_mock ( commands , &blk )
You can’t perform that action at this time.
0 commit comments