-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: 2.11.3
-
Component/s: Connections
-
None
-
(copied to CRM)
-
Fully Compatible
When the driver has to connect to a DNS-resolved host name, it currently performs the following operations:
1. Get IP addresses that the host name resolves to (ipv4 only for localhost, any for other host names)
2. Create a socket and connect to each resolved address in turn.
3. Return the first address connection to which succeeded.
4. Create another socket to the address in step 3, connect this socket and use it for subsequent operations.
The driver should instead use the socket obtained in step 2 for operations.
----------------
With a small patch to the driver we can observe multiple connections being established during Mongo::Server::ConnectionPool#create_and_add_connection:
diff --git a/lib/mongo/socket/tcp.rb b/lib/mongo/socket/tcp.rb index ca4123ff..defbc659 100644 --- a/lib/mongo/socket/tcp.rb +++ b/lib/mongo/socket/tcp.rb @@ -40,6 +40,7 @@ module Mongo def connect! Timeout.timeout(options[:connect_timeout], Error::SocketTimeoutError) do socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1) + puts "#{DateTime.now.strftime("%T:%L")} - connect! #{host}:#{port} - #{socket.inspect} - #{Thread.current.backtrace.join("\n")}" handle_errors { socket.connect(::Socket.pack_sockaddr_in(port, host)) } self end
The following test code (loading the patched driver) shows the socket descriptors being created once, but connected twice:
require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'mongo', path: "/path/to/mongo-ruby-driver" end Mongo::Logger.logger.level = Logger::FATAL client = Mongo::Client.new([ '127.0.0.1:27017' ], database: 'mydb', replica_set: 'replset', min_pool_size: 1, max_pool_size: 3) sleep 1 client.close
Cluster is a PSS.
Sample Output
Test code appends backtrace (removed below).
min_pool: 0 14:40:31:566 - connect! 127.0.0.1:27017 - #<Socket:fd 10> 14:40:31:566 - connect! 127.0.0.1:27017 - #<Socket:fd 10> 14:40:31:571 - connect! 127.0.0.1:27018 - #<Socket:fd 11> 14:40:31:572 - connect! 127.0.0.1:27017 - #<Socket:fd 12> 14:40:31:573 - connect! 127.0.0.1:27017 - #<Socket:fd 12> 14:40:31:574 - connect! 127.0.0.1:27019 - #<Socket:fd 13> 14:40:31:576 - connect! 127.0.0.1:27018 - #<Socket:fd 11> 14:40:31:576 - connect! 127.0.0.1:27019 - #<Socket:fd 13> min/max_pool: 1 13:53:04:736 - connect! 127.0.0.1:27017 - #<Socket:fd 10> 13:53:04:736 - connect! 127.0.0.1:27017 - #<Socket:fd 10> 13:53:04:746 - connect! 127.0.0.1:27018 - #<Socket:fd 11> 13:53:04:747 - connect! 127.0.0.1:27017 - #<Socket:fd 12> 13:53:04:751 - connect! 127.0.0.1:27018 - #<Socket:fd 11> 13:53:04:747 - connect! 127.0.0.1:27017 - #<Socket:fd 12> 13:53:04:753 - connect! 127.0.0.1:27019 - #<Socket:fd 13> 13:53:04:753 - connect! 127.0.0.1:27019 - #<Socket:fd 13> 13:53:04:760 - connect! 127.0.0.1:27018 - #<Socket:fd 14> 13:53:04:761 - connect! 127.0.0.1:27018 - #<Socket:fd 14> 13:53:04:767 - connect! 127.0.0.1:27019 - #<Socket:fd 15> 13:53:04:776 - connect! 127.0.0.1:27019 - #<Socket:fd 15> 13:53:04:778 - connect! 127.0.0.1:27017 - #<Socket:fd 16> 13:53:04:780 - connect! 127.0.0.1:27017 - #<Socket:fd 16>
- related to
-
RUBY-2162 Close sockets when connections fail
- Closed
- links to