Class: Mongo::Address
- Inherits:
-
Object
- Object
- Mongo::Address
- Extended by:
- Forwardable
- Defined in:
- lib/mongo/address.rb,
lib/mongo/address/ipv4.rb,
lib/mongo/address/ipv6.rb,
lib/mongo/address/unix.rb,
lib/mongo/address/validator.rb
Overview
Represents an address to a server, either with an IP address or socket path.
Defined Under Namespace
Modules: Validator Classes: IPv4, IPv6, Unix
Constant Summary collapse
- FAMILY_MAP =
Mapping from socket family to resolver class.
{ ::Socket::PF_UNIX => Unix, ::Socket::AF_INET6 => IPv6, ::Socket::AF_INET => IPv4 }.freeze
- LOCALHOST =
The localhost constant.
'localhost'.freeze
Instance Attribute Summary collapse
-
#host ⇒ String
readonly
Host The original host name.
- #options ⇒ Object readonly private
-
#port ⇒ Integer
readonly
Port The port.
-
#seed ⇒ String
readonly
Seed The seed address.
Instance Method Summary collapse
-
#==(other) ⇒ true, false
Check equality of the address to another.
-
#eql?(other) ⇒ true, false
Check equality for hashing.
-
#hash ⇒ Integer
Calculate the hash value for the address.
-
#initialize(seed, options = {}) ⇒ Address
constructor
Initialize the address.
-
#inspect ⇒ String
Get a pretty printed address inspection.
-
#socket(socket_timeout, opts = {}) ⇒ Mongo::Socket::SSL | Mongo::Socket::TCP | Mongo::Socket::Unix
private
Get a socket for the address stored in this object, given the options.
-
#to_s ⇒ String
Get the address as a string.
Constructor Details
#initialize(seed, options = {}) ⇒ Address
Initialize the address.
75 76 77 78 79 80 81 82 |
# File 'lib/mongo/address.rb', line 75 def initialize(seed, = {}) if seed.nil? raise ArgumentError, "address must be not nil" end @seed = seed @host, @port = parse_host_port @options = Hash[.map { |k, v| [k.to_sym, v] }] end |
Instance Attribute Details
#host ⇒ String (readonly)
Returns host The original host name.
88 89 90 |
# File 'lib/mongo/address.rb', line 88 def host @host end |
#options ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
94 95 96 |
# File 'lib/mongo/address.rb', line 94 def @options end |
#port ⇒ Integer (readonly)
Returns port The port.
91 92 93 |
# File 'lib/mongo/address.rb', line 91 def port @port end |
#seed ⇒ String (readonly)
Returns seed The seed address.
85 86 87 |
# File 'lib/mongo/address.rb', line 85 def seed @seed end |
Instance Method Details
#==(other) ⇒ true, false
Check equality of the address to another.
106 107 108 109 |
# File 'lib/mongo/address.rb', line 106 def ==(other) return false unless other.is_a?(Address) host == other.host && port == other.port end |
#eql?(other) ⇒ true, false
Check equality for hashing.
121 122 123 |
# File 'lib/mongo/address.rb', line 121 def eql?(other) self == other end |
#hash ⇒ Integer
Calculate the hash value for the address.
133 134 135 |
# File 'lib/mongo/address.rb', line 133 def hash [ host, port ].hash end |
#inspect ⇒ String
Get a pretty printed address inspection.
145 146 147 |
# File 'lib/mongo/address.rb', line 145 def inspect "#<Mongo::Address:0x#{object_id} address=#{to_s}>" end |
#socket(socket_timeout, opts = {}) ⇒ Mongo::Socket::SSL | Mongo::Socket::TCP | Mongo::Socket::Unix
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Get a socket for the address stored in this object, given the options.
If the address stored in this object looks like a Unix path, this method returns a Unix domain socket for this path.
Otherwise, this method attempts to resolve the address stored in this object to IPv4 and IPv6 addresses using Socket#getaddrinfo, then connects to the resulting addresses and returns the socket of the first successful connection. The order in which address families (IPv4/IPV6) are tried is the same order in which the addresses are returned by getaddrinfo
, and is determined by the host system.
Name resolution is performed on each socket
call. This is done so that any changes to which addresses the host names used as seeds or in server configuration resolve to are immediately noticed by the driver, even if a socket has been connected to the affected host name/address before. However, note that DNS TTL values may still affect when a change to a host address is noticed by the driver.
This method propagates any exceptions raised during DNS resolution and subsequent connection attempts. In case of a host name resolving to multiple IP addresses, the error raised by the last attempt is propagated to the caller. This method does not map exceptions to Mongo::Error subclasses, and may raise any subclass of Exception.
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/mongo/address.rb', line 219 def socket(socket_timeout, opts = {}) csot = !!opts[:csot] opts = { connect_timeout: Server::CONNECT_TIMEOUT, }.update().update(Hash[opts.map { |k, v| [k.to_sym, v] }]) map_exceptions(csot) do if seed.downcase =~ Unix::MATCH specific_address = Unix.new(seed.downcase) return specific_address.socket(socket_timeout, opts) end # When the driver connects to "localhost", it only attempts IPv4 # connections. When the driver connects to other hosts, it will # attempt both IPv4 and IPv6 connections. family = (host == LOCALHOST) ? ::Socket::AF_INET : ::Socket::AF_UNSPEC error = nil # Sometimes Socket#getaddrinfo returns the same info more than once # (multiple identical items in the returned array). It does not make # sense to try to connect to the same address more than once, thus # eliminate duplicates here. infos = ::Socket.getaddrinfo(host, nil, family, ::Socket::SOCK_STREAM) results = infos.map do |info| [info[4], info[3]] end.uniq results.each do |family, address_str| begin specific_address = FAMILY_MAP[family].new(address_str, port, host) socket = specific_address.socket(socket_timeout, opts) return socket rescue IOError, SystemCallError, Error::SocketTimeoutError, Error::SocketError => e error = e end end raise error end end |
#to_s ⇒ String
Get the address as a string.
265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/mongo/address.rb', line 265 def to_s if port if host.include?(':') "[#{host}]:#{port}" else "#{host}:#{port}" end else host end end |