Skip to content

Commit

Permalink
Fix performance regression in do_write(s)
Browse files Browse the repository at this point in the history
This causes significant performance issues when using large (>10meg) writes

Fix by adjusting the buffer write function to clear the buffer once, rather than
piece by piece, avoiding a case where a large write (in our case, around
70mbytes) will consume 100% of CPU. This takes a webrick GET request via SSL
from around 200kbyts/sec and consuming 100% of a core, to line speed on gigabit
ethernet and 6% cpu utlization.
  • Loading branch information
anotherjaymz committed Feb 5, 2024
1 parent ccc1594 commit d4389b4
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions lib/openssl/buffering.rb
Original file line number Diff line number Diff line change
Expand Up @@ -348,13 +348,18 @@ def do_write(s)
@wbuffer << s
@wbuffer.force_encoding(Encoding::BINARY)
@sync ||= false
if @sync or @wbuffer.size > BLOCK_SIZE
until @wbuffer.empty?
begin
nwrote = syswrite(@wbuffer)
rescue Errno::EAGAIN
retry
buffer_size = @wbuffer.size
if @sync or buffer_size > BLOCK_SIZE
nwrote = 0
begin
while nwrote < buffer_size do
begin
nwrote += syswrite(@wbuffer[nwrote, buffer_size - nwrote])
rescue Errno::EAGAIN
retry
end
end
ensure
@wbuffer[0, nwrote] = ""
end
end
Expand Down

0 comments on commit d4389b4

Please sign in to comment.