diff --git a/.rubocop.yml b/.rubocop.yml index fb20d92e9..96fb535ce 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -57,6 +57,9 @@ Style/ParallelAssignment: Style/NumericPredicate: Enabled: false +Style/IfUnlessModifier: + Enabled: false + Style/SignalException: Exclude: - 'lib/redis/connection/synchrony.rb' diff --git a/lib/redis/connection/ruby.rb b/lib/redis/connection/ruby.rb index a9aca333d..009afb0bd 100644 --- a/lib/redis/connection/ruby.rb +++ b/lib/redis/connection/ruby.rb @@ -49,43 +49,47 @@ def gets end def _read_from_socket(nbytes) - begin - read_nonblock(nbytes) - rescue IO::WaitReadable - if IO.select([self], nil, nil, @timeout) - retry - else - raise Redis::TimeoutError - end - rescue IO::WaitWritable - if IO.select(nil, [self], nil, @timeout) - retry - else - raise Redis::TimeoutError + loop do + case chunk = read_nonblock(nbytes, exception: false) + when :wait_readable + unless IO.select([self], nil, nil, @timeout) + raise Redis::TimeoutError + end + when :wait_writable + unless IO.select(nil, [self], nil, @timeout) + raise Redis::TimeoutError + end + when nil + raise Errno::ECONNRESET + when String + return chunk end end - rescue EOFError - raise Errno::ECONNRESET end def _write_to_socket(data) - begin - write_nonblock(data) - rescue IO::WaitWritable - if IO.select(nil, [self], nil, @write_timeout) - retry - else - raise Redis::TimeoutError - end - rescue IO::WaitReadable - if IO.select([self], nil, nil, @write_timeout) - retry - else - raise Redis::TimeoutError + total_bytes_written = 0 + loop do + case bytes_written = write_nonblock(data, exception: false) + when :wait_readable + unless IO.select([self], nil, nil, @timeout) + raise Redis::TimeoutError + end + when :wait_writable + unless IO.select(nil, [self], nil, @timeout) + raise Redis::TimeoutError + end + when nil + raise Errno::ECONNRESET + when Integer + total_bytes_written += bytes_written + if bytes_written < data.bytesize + data.slice!(0, bytes_written) + else + return total_bytes_written + end end end - rescue EOFError - raise Errno::ECONNRESET end def write(data) diff --git a/test/internals_test.rb b/test/internals_test.rb index 27e99bb7b..e19b56690 100644 --- a/test/internals_test.rb +++ b/test/internals_test.rb @@ -244,7 +244,7 @@ def close_on_connection(seq) else raise "Expected SELECT" end - unless seq.include?(n) # rubocop:disable Style/IfUnlessModifier + unless seq.include?(n) session.write("+#{n}\r\n") while read_command.call(session) end end