Skip to content

Commit

Permalink
Rescue IO::WaitReadable instead of EAGAIN for blocking read (#2121)
Browse files Browse the repository at this point in the history
* Add test for waiting with an open client connection

* Rescue IO::WaitReadable instead of EAGAIN for blocking read
On Windows, `read_nonblock` raises `Errno::EWOULDBLOCK` if a blocking read would occur, which is a different value from `Errno::EAGAIN`. Both of these errors are extended by `IO::WaitReadable` which is Ruby's recommended exception class for retrying `read_nonblock`.
  • Loading branch information
wjordan committed Feb 21, 2020
1 parent a948c16 commit adb6170
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
1 change: 1 addition & 0 deletions History.md
Expand Up @@ -13,6 +13,7 @@
* Windows update extconf.rb for use with ssp and varied Ruby/MSYS2 combinations (#2069)
* Preserve `BUNDLE_GEMFILE` env var when using `prune_bundler` (#1893)
* Send 408 request timeout even when queue requests is disabled (#2119)
* Rescue IO::WaitReadable instead of EAGAIN for blocking read (#2121)

* Refactor
* Remove unused loader argument from Plugin initializer (#2095)
Expand Down
4 changes: 2 additions & 2 deletions lib/puma/client.rb
Expand Up @@ -153,7 +153,7 @@ def try_to_finish

begin
data = @io.read_nonblock(CHUNK_SIZE)
rescue Errno::EAGAIN
rescue IO::WaitReadable
return false
rescue SystemCallError, IOError, EOFError
raise ConnectionError, "Connection error detected during read"
Expand Down Expand Up @@ -349,7 +349,7 @@ def read_body

begin
chunk = @io.read_nonblock(want)
rescue Errno::EAGAIN
rescue IO::WaitReadable
return false
rescue SystemCallError, IOError
raise ConnectionError, "Connection error detected during read"
Expand Down
13 changes: 13 additions & 0 deletions test/test_puma_server.rb
Expand Up @@ -754,4 +754,17 @@ def test_request_body_wait_chunked
# it is set to a reasonable number.
assert_operator request_body_wait, :>=, 900
end

def test_open_connection_wait
server_run app: ->(_) { [200, {}, ["Hello"]] }
s = send_http nil
sleep 0.1
s << "GET / HTTP/1.0\r\n\r\n"
assert_equal 'Hello', s.readlines.last
end

def test_open_connection_wait_no_queue
@server = Puma::Server.new @app, @events, queue_requests: false
test_open_connection_wait
end
end

0 comments on commit adb6170

Please sign in to comment.