lib/async/io/host_endpoint.rb in async-io-1.20.0 vs lib/async/io/host_endpoint.rb in async-io-1.21.0
- old
+ new
@@ -41,19 +41,28 @@
# Try to connect to the given host by connecting to each address in sequence until a connection is made.
# @yield [Socket] the socket which is being connected, may be invoked more than once
# @return [Socket] the connected socket
# @raise if no connection could complete successfully
- def connect(&block)
+ def connect
last_error = nil
+ task = Task.current
+
Addrinfo.foreach(*@specification) do |address|
begin
- return Socket.connect(address, **@options, &block)
- # This is a little bit risky. In theory, what it is supposed to do is catch the failed connection, and try the next address. In practice, it can catch other kinds of failures. Ideally, it only applies to `#connect`, but it also applies to what's executed in `&block`.
- rescue
+ wrapper = Socket.connect(address, **@options, task: task)
+ rescue Errno::ECONNREFUSED, Errno::ENETUNREACH, Errno::EAGAIN
last_error = $!
+ else
+ return wrapper unless block_given?
+
+ begin
+ return yield wrapper, task
+ ensure
+ wrapper.close
+ end
end
end
raise last_error
end
@@ -76,16 +85,23 @@
end
end
end
class Endpoint
- # args: nodename, service, family, socktype, protocol, flags
+ # @param args nodename, service, family, socktype, protocol, flags. `socktype` will be set to Socket::SOCK_STREAM.
+ # @param options keyword arguments passed on to {HostEndpoint#initialize}
+ #
+ # @return [HostEndpoint]
def self.tcp(*args, **options)
args[3] = ::Socket::SOCK_STREAM
HostEndpoint.new(args, **options)
end
+ # @param args nodename, service, family, socktype, protocol, flags. `socktype` will be set to Socket::SOCK_DGRAM.
+ # @param options keyword arguments passed on to {HostEndpoint#initialize}
+ #
+ # @return [HostEndpoint]
def self.udp(*args, **options)
args[3] = ::Socket::SOCK_DGRAM
HostEndpoint.new(args, **options)
end