Skip to content

Commit

Permalink
Working example of BasicSocket#readable?.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Apr 17, 2024
1 parent 115dbf6 commit 07e6802
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 9 deletions.
74 changes: 65 additions & 9 deletions examples/http1/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,70 @@
require 'async/http/endpoint'
require 'protocol/http1/connection'

Async do
endpoint = Async::HTTP::Endpoint.parse("http://localhost:8080")

peer = endpoint.connect
# class IO
# def readable?
# if self.wait_readable(0).nil?
# # timeout means it is not eof
# return true
# else
# !self.eof?
# end
# rescue Errno::EPIPE, Errno::ECONNRESET
# false
# end
# end

class IO
def readable?
!self.closed?
end
end

class BasicSocket
# Is it likely that the socket is still connected?
# May return false positive, but won't return false negative.
def readable?
return false unless super

# If we can wait for the socket to become readable, we know that the socket may still be open.
result = self.recv_nonblock(1, Socket::MSG_PEEK, exception: false)

# No data was available - newer Ruby can return nil instead of empty string:
return false if result.nil?

# Either there was some data available, or we can wait to see if there is data avaialble.
return !result.empty? || result == :wait_readable

rescue Errno::ECONNRESET
# This might be thrown by recv_nonblock.
return false
end
end

def connect(endpoint)
peer = endpoint.connect.to_io

puts "Connected to #{peer} #{peer.remote_address.inspect}"

# IO Buffering...
stream = Async::IO::Stream.new(peer)
client = Protocol::HTTP1::Connection.new(stream)
return Protocol::HTTP1::Connection.new(peer)
end

Async do
endpoint = Async::HTTP::Endpoint.parse("http://localhost:8080")

client = connect(endpoint)

puts "Writing request..."
3.times do
10.times do
puts "Writing request..."
# How do we know here whether the client is still good?
unless client.stream.readable?
puts "Client is not readable, closing..."
client.close

puts "Reconnecting..."
client = connect(endpoint)
end

client.write_request("localhost", "GET", "/", "HTTP/1.1", [["Accept", "*/*"]])
client.write_body("HTTP/1.1", nil)

Expand All @@ -33,6 +84,11 @@

puts "Got response: #{response.inspect}"
puts body&.read
rescue Errno::ECONNRESET, Errno::EPIPE, EOFError
puts "Connection reset by peer."

# Reconnect and try again:
client = connect(endpoint)
end

puts "Closing client..."
Expand Down
5 changes: 5 additions & 0 deletions examples/http1/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@
connection.write_response(version, 200, [["Content-Type", "text/plain"]])
connection.write_body(version, Protocol::HTTP::Body::Buffered.wrap(["Hello World"]))

# Simulate random disconnects:
break if rand < 0.5

break unless connection.persistent
end
ensure
client&.close
end
end

0 comments on commit 07e6802

Please sign in to comment.