Skip to content

Commit

Permalink
Merge pull request #193 from redis-rb/workaround-ssl-socket-buffer-clear
Browse files Browse the repository at this point in the history
Workaround SSLSocket always clearing the buffer
  • Loading branch information
casperisfine authored Apr 16, 2024
2 parents c550381 + 49b0d16 commit 336ce1c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 5 deletions.
18 changes: 17 additions & 1 deletion lib/redis_client/ruby_connection/buffered_io.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ def ensure_remaining(bytes)

def fill_buffer(strict, size = @chunk_size)
remaining = size
start = @offset - @buffer.bytesize
buffer_size = @buffer.bytesize
start = @offset - buffer_size
empty_buffer = start >= 0

loop do
Expand All @@ -199,12 +200,27 @@ def fill_buffer(strict, size = @chunk_size)
else
@io.read_nonblock([remaining, @chunk_size].max, exception: false)
end

case bytes
when :wait_readable
# Ref: https://github.com/redis-rb/redis-client/issues/190
# SSLSocket always clear the provided buffer, even when it didn't
# read anything. So we need to reset the offset accordingly.
if empty_buffer && @buffer.empty?
@offset -= buffer_size
end

unless @io.to_io.wait_readable(@read_timeout)
raise ReadTimeoutError, "Waited #{@read_timeout} seconds" unless @blocking_reads
end
when :wait_writable
# Ref: https://github.com/redis-rb/redis-client/issues/190
# SSLSocket always clear the provided buffer, even when it didn't
# read anything. So we need to reset the offset accordingly.
if empty_buffer && @buffer.empty?
@offset -= buffer_size
end

@io.to_io.wait_writable(@write_timeout) or raise(WriteTimeoutError, "Waited #{@write_timeout} seconds")
when nil
raise EOFError
Expand Down
4 changes: 2 additions & 2 deletions test/redis_client/middlewares_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ def test_multi_instrumentation
end

module DummyMiddleware
def call(command, _config)
def call(command, _config, &_)
command
end

def call_pipelined(commands, _config)
def call_pipelined(commands, _config, &_)
commands
end
end
Expand Down
4 changes: 2 additions & 2 deletions test/redis_client_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def test_dns_resolution_failure

def test_older_server
fake_redis5_driver = Class.new(RedisClient::RubyConnection) do
def call_pipelined(commands, *)
def call_pipelined(commands, *, &_)
if commands.any? { |c| c == ["HELLO", "3"] }
raise RedisClient::CommandError, "ERR unknown command `HELLO`, with args beginning with: `3`"
else
Expand All @@ -71,7 +71,7 @@ def call_pipelined(commands, *)

def test_redis_6_server_with_missing_hello_command
fake_redis6_driver = Class.new(RedisClient::RubyConnection) do
def call_pipelined(commands, *)
def call_pipelined(commands, *, &_)
if commands.any? { |c| c == ["HELLO", "3"] }
raise RedisClient::CommandError, "ERR unknown command 'HELLO'"
else
Expand Down

0 comments on commit 336ce1c

Please sign in to comment.