Class: Mongo::Address

Inherits:
Object
  • Object
show all
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.

Since:

  • 2.0.0

Defined Under Namespace

Modules: Validator Classes: IPv4, IPv6, Unix

Constant Summary collapse

FAMILY_MAP =

Mapping from socket family to resolver class.

Since:

  • 2.0.0

{
  ::Socket::PF_UNIX => Unix,
  ::Socket::AF_INET6 => IPv6,
  ::Socket::AF_INET => IPv4
}.freeze
LOCALHOST =

The localhost constant.

Since:

  • 2.1.0

'localhost'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(seed, options = {}) ⇒ Address

Initialize the address.

Examples:

Initialize the address with a DNS entry and port.

Mongo::Address.new("app.example.com:27017")

Initialize the address with a DNS entry and no port.

Mongo::Address.new("app.example.com")

Initialize the address with an IPV4 address and port.

Mongo::Address.new("127.0.0.1:27017")

Initialize the address with an IPV4 address and no port.

Mongo::Address.new("127.0.0.1")

Initialize the address with an IPV6 address and port.

Mongo::Address.new("[::1]:27017")

Initialize the address with an IPV6 address and no port.

Mongo::Address.new("[::1]")

Initialize the address with a unix socket.

Mongo::Address.new("/path/to/socket.sock")

Parameters:

  • seed (String)

    The provided address.

  • options (Hash) (defaults to: {})

    The address options.

Options Hash (options):

  • :connect_timeout (Float)

    Connect timeout.

Since:

  • 2.0.0



75
76
77
78
79
80
81
82
# File 'lib/mongo/address.rb', line 75

def initialize(seed, options = {})
  if seed.nil?
    raise ArgumentError, "address must be not nil"
  end
  @seed = seed
  @host, @port = parse_host_port
  @options = Hash[options.map { |k, v| [k.to_sym, v] }]
end

Instance Attribute Details

#hostString (readonly)

Returns host The original host name.

Returns:

  • (String)

    host The original host name.

Since:

  • 2.0.0



88
89
90
# File 'lib/mongo/address.rb', line 88

def host
  @host
end

#optionsObject (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.

Since:

  • 2.0.0



94
95
96
# File 'lib/mongo/address.rb', line 94

def options
  @options
end

#portInteger (readonly)

Returns port The port.

Returns:

  • (Integer)

    port The port.

Since:

  • 2.0.0



91
92
93
# File 'lib/mongo/address.rb', line 91

def port
  @port
end

#seedString (readonly)

Returns seed The seed address.

Returns:

  • (String)

    seed The seed address.

Since:

  • 2.0.0



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.

Examples:

Check address equality.

address == other

Parameters:

  • other (Object)

    The other object.

Returns:

  • (true, false)

    If the objects are equal.

Since:

  • 2.0.0



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.

Examples:

Check hashing equality.

address.eql?(other)

Parameters:

  • other (Object)

    The other object.

Returns:

  • (true, false)

    If the objects are equal.

Since:

  • 2.2.0



121
122
123
# File 'lib/mongo/address.rb', line 121

def eql?(other)
  self == other
end

#hashInteger

Calculate the hash value for the address.

Examples:

Calculate the hash value.

address.hash

Returns:

  • (Integer)

    The hash value.

Since:

  • 2.0.0



133
134
135
# File 'lib/mongo/address.rb', line 133

def hash
  [ host, port ].hash
end

#inspectString

Get a pretty printed address inspection.

Examples:

Get the address inspection.

address.inspect

Returns:

  • (String)

    The nice inspection string.

Since:

  • 2.0.0



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.

Examples:

Get a socket.

address.socket(5, :ssl => true)

Parameters:

  • socket_timeout (Float)

    The socket timeout.

  • opts (Hash) (defaults to: {})

    The options.

Options Hash (opts):

  • :connect_timeout (Float)

    Connect timeout.

  • :csot (Boolean)

    Whether the client-side operation timeout should be considered when connecting the socket. This option influences only what errors will be raised if timeout expires.

  • :ssl (true | false)

    Whether to use SSL.

  • :ssl_ca_cert (String)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_ca_cert_object (Array<OpenSSL::X509::Certificate>)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_ca_cert_string (String)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_cert (String)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_cert_object (OpenSSL::X509::Certificate)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_cert_string (String)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_key (String)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_key_object (OpenSSL::PKey)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_key_pass_phrase (String)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_key_string (String)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_verify (true, false)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_verify_certificate (true, false)

    Same as the corresponding Client/Socket::SSL option.

  • :ssl_verify_hostname (true, false)

    Same as the corresponding Client/Socket::SSL option.

Returns:

Raises:

Since:

  • 2.0.0



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(options).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_sString

Get the address as a string.

Examples:

Get the address as a string.

address.to_s

Returns:

  • (String)

    The nice string.

Since:

  • 2.0.0



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