Skip to content

Commit fa24f62

Browse files
authored
Merge pull request #876 from estolfo/RUBY-1222-conn-timeout-2
RUBY-1222 Use connect_timeout when determining address family
2 parents a66ea77 + b1d936f commit fa24f62

File tree

18 files changed

+326
-72
lines changed

18 files changed

+326
-72
lines changed

lib/mongo/address.rb

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ def hash
119119
def initialize(seed, options = {})
120120
@seed = seed
121121
@host, @port = parse_host_port
122+
@options = options
122123
end
123124

124125
# Get a pretty printed address inspection.
@@ -138,15 +139,15 @@ def inspect
138139
# @example Get a socket.
139140
# address.socket(5, :ssl => true)
140141
#
141-
# @param [ Float ] timeout The socket timeout.
142+
# @param [ Float ] socket_timeout The socket timeout.
142143
# @param [ Hash ] ssl_options SSL options.
143144
#
144145
# @return [ Pool::Socket::SSL, Pool::Socket::TCP, Pool::Socket::Unix ] The socket.
145146
#
146147
# @since 2.0.0
147-
def socket(timeout, ssl_options = {})
148-
@resolver ||= initialize_resolver!(timeout, ssl_options)
149-
@resolver.socket(timeout, ssl_options)
148+
def socket(socket_timeout, ssl_options = {})
149+
@resolver ||= initialize_resolver!(ssl_options)
150+
@resolver.socket(socket_timeout, ssl_options)
150151
end
151152

152153
# Get the address as a string.
@@ -161,19 +162,33 @@ def to_s
161162
port ? "#{host}:#{port}" : host
162163
end
163164

165+
# Connect a socket.
166+
#
167+
# @example Connect a socket.
168+
# address.connect_socket!(socket)
169+
#
170+
# @since 2.4.3
171+
def connect_socket!(socket)
172+
socket.connect!(connect_timeout)
173+
end
174+
164175
private
165176

166-
def initialize_resolver!(timeout, ssl_options)
177+
def connect_timeout
178+
@connect_timeout ||= @options[:connect_timeout] || Server::CONNECT_TIMEOUT
179+
end
180+
181+
def initialize_resolver!(ssl_options)
167182
return Unix.new(seed.downcase) if seed.downcase =~ Unix::MATCH
168183

169184
family = (host == LOCALHOST) ? ::Socket::AF_INET : ::Socket::AF_UNSPEC
170185
error = nil
171186
::Socket.getaddrinfo(host, nil, family, ::Socket::SOCK_STREAM).each do |info|
172187
begin
173188
res = FAMILY_MAP[info[4]].new(info[3], port, host)
174-
res.socket(timeout, ssl_options).connect!.close
189+
res.socket(connect_timeout, ssl_options).connect!(connect_timeout).close
175190
return res
176-
rescue IOError, SystemCallError, Error::SocketError => e
191+
rescue IOError, SystemCallError, Error::SocketTimeoutError, Error::SocketError => e
177192
error = e
178193
end
179194
end

lib/mongo/address/ipv4.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,17 @@ def initialize(host, port, host_name=nil)
7777
# @example Get an IPv4 socket.
7878
# ipv4.socket(5, :ssl => true)
7979
#
80-
# @param [ Float ] timeout The socket timeout.
80+
# @param [ Float ] socket_timeout The socket timeout.
8181
# @param [ Hash ] ssl_options SSL options.
8282
#
8383
# @return [ Pool::Socket::SSL, Pool::Socket::TCP ] The socket.
8484
#
8585
# @since 2.0.0
86-
def socket(timeout, ssl_options = {})
86+
def socket(socket_timeout, ssl_options = {})
8787
unless ssl_options.empty?
88-
Socket::SSL.new(host, port, host_name, timeout, Socket::PF_INET, ssl_options)
88+
Socket::SSL.new(host, port, host_name, socket_timeout, Socket::PF_INET, ssl_options)
8989
else
90-
Socket::TCP.new(host, port, timeout, Socket::PF_INET)
90+
Socket::TCP.new(host, port, socket_timeout, Socket::PF_INET)
9191
end
9292
end
9393
end

lib/mongo/address/ipv6.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,17 @@ def initialize(host, port, host_name=nil)
7272
# @example Get an IPv6 socket.
7373
# ipv4.socket(5, :ssl => true)
7474
#
75-
# @param [ Float ] timeout The socket timeout.
75+
# @param [ Float ] socket_timeout The socket timeout.
7676
# @param [ Hash ] ssl_options SSL options.
7777
#
7878
# @return [ Pool::Socket::SSL, Pool::Socket::TCP ] The socket.
7979
#
8080
# @since 2.0.0
81-
def socket(timeout, ssl_options = {})
81+
def socket(socket_timeout, ssl_options = {})
8282
unless ssl_options.empty?
83-
Socket::SSL.new(host, port, host_name, timeout, Socket::PF_INET6, ssl_options)
83+
Socket::SSL.new(host, port, host_name, socket_timeout, Socket::PF_INET6, ssl_options)
8484
else
85-
Socket::TCP.new(host, port, timeout, Socket::PF_INET6)
85+
Socket::TCP.new(host, port, socket_timeout, Socket::PF_INET6)
8686
end
8787
end
8888
end

lib/mongo/address/unix.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ def initialize(host, port=nil, host_name=nil)
6868
# @return [ Pool::Socket::Unix ] The socket.
6969
#
7070
# @since 2.0.0
71-
def socket(timeout, ssl_options = {})
72-
Socket::Unix.new(host, timeout)
71+
def socket(socket_timeout, ssl_options = {})
72+
Socket::Unix.new(host, socket_timeout)
7373
end
7474
end
7575
end

lib/mongo/cluster.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def ==(other)
9696
#
9797
# @since 2.0.0
9898
def add(host)
99-
address = Address.new(host)
99+
address = Address.new(host, options)
100100
if !addresses.include?(address)
101101
if addition_allowed?(address)
102102
@update_lock.synchronize { @addresses.push(address) }

lib/mongo/server.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ class Server
4444
# @return [ Monitoring ] monitoring The monitoring.
4545
attr_reader :monitoring
4646

47+
# The default time in seconds to timeout a connection attempt.
48+
#
49+
# @since 2.4.3
50+
CONNECT_TIMEOUT = 10.freeze
51+
4752
# Get the description from the monitor and scan on monitor.
4853
def_delegators :monitor, :description, :scan!, :heartbeat_frequency, :last_scan
4954
alias :heartbeat_frequency_seconds :heartbeat_frequency

lib/mongo/server/connectable.rb

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,6 @@ def connected?
6868
!!@socket && @socket.alive?
6969
end
7070

71-
# Get the timeout to execute an operation on a socket.
72-
#
73-
# @example Get the timeout to execute an operation on a socket.
74-
# connection.timeout
75-
#
76-
# @return [ Float ] The operation timeout in seconds.
77-
#
78-
# @since 2.0.0
79-
def timeout
80-
@timeout ||= options[:socket_timeout]
81-
end
82-
8371
protected
8472

8573
attr_reader :socket

lib/mongo/server/connection.rb

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ class Connection
5959
# @since 2.0.0
6060
def connect!
6161
unless socket && socket.connectable?
62-
@socket = address.socket(timeout, ssl_options)
63-
socket.connect!
62+
@socket = address.socket(socket_timeout, ssl_options)
63+
address.connect_socket!(socket)
6464
handshake!
6565
authenticate!
6666
end
@@ -156,6 +156,20 @@ def ping
156156
end
157157
end
158158

159+
# Get the timeout to execute an operation on a socket.
160+
#
161+
# @example Get the timeout to execute an operation on a socket.
162+
# connection.timeout
163+
#
164+
# @return [ Float ] The operation timeout in seconds.
165+
#
166+
# @since 2.0.0
167+
def socket_timeout
168+
@timeout ||= options[:socket_timeout]
169+
end
170+
# @deprecated Please use :socket_timeout instead. Will be removed in 3.0.0
171+
alias :timeout :socket_timeout
172+
159173
private
160174

161175
def deliver(messages)

lib/mongo/server/monitor/connection.rb

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class Connection
4141
# The default time in seconds to timeout a connection attempt.
4242
#
4343
# @since 2.1.2
44+
#
45+
# @deprecated Please use Server::CONNECT_TIMEOUT instead. Will be removed in 3.0.0
4446
CONNECT_TIMEOUT = 10.freeze
4547

4648
# Send the preserialized ismaster call.
@@ -73,8 +75,8 @@ def ismaster
7375
# @since 2.0.0
7476
def connect!
7577
unless socket && socket.connectable?
76-
@socket = address.socket(timeout, ssl_options)
77-
socket.connect!
78+
@socket = address.socket(socket_timeout, ssl_options)
79+
address.connect_socket!(socket)
7880
handshake!
7981
end
8082
true
@@ -122,17 +124,21 @@ def initialize(address, options = {})
122124
@pid = Process.pid
123125
end
124126

125-
# Get the connection timeout.
127+
# Get the socket timeout.
126128
#
127-
# @example Get the connection timeout.
128-
# connection.timeout
129+
# @example Get the socket timeout.
130+
# connection.socket_timeout
129131
#
130-
# @return [ Float ] The connection timeout in seconds.
132+
# @return [ Float ] The socket timeout in seconds. Note that the Monitor's connection
133+
# uses the connect timeout value for calling ismaster. See the Server Discovery and
134+
# Monitoring specification for details.
131135
#
132-
# @since 2.0.0
133-
def timeout
134-
@timeout ||= options[:connect_timeout] || CONNECT_TIMEOUT
136+
# @since 2.4.3
137+
def socket_timeout
138+
@timeout ||= options[:connect_timeout] || Server::CONNECT_TIMEOUT
135139
end
140+
# @deprecated Please use :socket_timeout instead. Will be removed in 3.0.0
141+
alias :timeout :socket_timeout
136142

137143
private
138144

lib/mongo/socket/ssl.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class SSL < Socket
3838
# @return [ Integer ] port The port to connect to.
3939
attr_reader :port
4040

41-
# @return [ Float ] timeout The connection timeout.
41+
# @return [ Float ] timeout The socket timeout.
4242
attr_reader :timeout
4343

4444
# Establishes a socket connection.
@@ -52,8 +52,8 @@ class SSL < Socket
5252
# @return [ SSL ] The connected socket instance.
5353
#
5454
# @since 2.0.0
55-
def connect!
56-
Timeout.timeout(timeout, Error::SocketTimeoutError) do
55+
def connect!(connect_timeout = nil)
56+
Timeout.timeout(connect_timeout, Error::SocketTimeoutError) do
5757
handle_errors { @tcp_socket.connect(::Socket.pack_sockaddr_in(port, host)) }
5858
@socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
5959
@socket.hostname = @host_name unless BSON::Environment.jruby?

0 commit comments

Comments
 (0)