Class: Mongo::Server::Monitor::Connection Private

Inherits:
ConnectionCommon show all
Includes:
Loggable
Defined in:
lib/mongo/server/monitor/connection.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

This class models the monitor connections and their behavior.

Since:

  • 2.0.0

Direct Known Subclasses

PushMonitor::Connection

Constant Summary collapse

ISMASTER =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The command used for determining server status.

The case matters here for fail points.

Since:

  • 2.2.0

{ isMaster: 1 }.freeze
ISMASTER_OP_MSG =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The command used for determining server status formatted for an OP_MSG (server versions >= 3.6).

The case matters here for fail points.

Since:

  • 2.5.0

{
  isMaster: 1,
  '$db' => Database::ADMIN,
}.freeze
ISMASTER_MESSAGE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The constant for the ismaster command.

Since:

  • 2.2.0

Protocol::Query.new(Database::ADMIN, Database::COMMAND, ISMASTER, :limit => -1)
ISMASTER_OP_MSG_MESSAGE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The constant for the ismaster command as an OP_MSG (server versions >= 3.6).

Since:

  • 2.5.0

Protocol::Msg.new([], {}, ISMASTER_OP_MSG)
ISMASTER_BYTES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The raw bytes for the ismaster message.

Since:

  • 2.2.0

ISMASTER_MESSAGE.serialize.to_s.freeze
ISMASTER_OP_MSG_BYTES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The raw bytes for the ismaster OP_MSG message (server versions >= 3.6).

Since:

  • 2.5.0

ISMASTER_OP_MSG_MESSAGE.serialize.to_s.freeze

Constants included from Loggable

Loggable::PREFIX

Instance Attribute Summary collapse

Attributes inherited from ConnectionCommon

#compressor, #pid

Instance Method Summary collapse

Methods included from Loggable

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger

Methods inherited from ConnectionCommon

#connected?

Constructor Details

#initialize(address, options = {}) ⇒ Connection

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.

Note:

Monitoring connections do not authenticate.

Creates a new connection object to the specified target address with the specified options.

The constructor does not perform any I/O (and thus does not create sockets nor handshakes); call connect! method on the connection object to create the network connection.

Parameters:

  • address (Mongo::Address)

    The address the connection is for.

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

    The connection options.

Options Hash (options):

  • :app_metadata (Mongo::Server::Monitor::AppMetadata)

    Metadata to use for handshake. If missing or nil, handshake will not be performed. Although a Mongo::Server::AppMetadata instance will also work, monitoring connections are meant to use Mongo::Server::Monitor::AppMetadata instances in order to omit performing SCRAM negotiation with the server, as monitoring sockets do not authenticate.

  • :compressors (Array<String>)

    A list of potential compressors to use, in order of preference. The driver chooses the first compressor that is also supported by the server. Currently the driver only supports ‘zlib’.

  • :connect_timeout (Float)

    The timeout, in seconds, to use for network operations. This timeout is used for all socket operations rather than connect calls only, contrary to what the name implies,

Since:

  • 2.0.0



93
94
95
96
97
98
99
100
# File 'lib/mongo/server/monitor/connection.rb', line 93

def initialize(address, options = {})
  @address = address
  @options = options.dup.freeze
  @app_metadata = options[:app_metadata]
  @socket = nil
  @pid = Process.pid
  @compressor = nil
end

Instance Attribute Details

#addressMongo::Address (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.

Returns address The address to connect to.

Returns:

Since:

  • 2.0.0



106
107
108
# File 'lib/mongo/server/monitor/connection.rb', line 106

def address
  @address
end

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

Returns options The passed in options.

Returns:

  • (Hash)

    options The passed in options.

Since:

  • 2.0.0



103
104
105
# File 'lib/mongo/server/monitor/connection.rb', line 103

def options
  @options
end

#server_connection_idObject (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



121
122
123
# File 'lib/mongo/server/monitor/connection.rb', line 121

def server_connection_id
  @server_connection_id
end

Instance Method Details

#connect!true

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.

Note:

This method mutates the connection class by setting a socket if one previously did not exist.

Establishes a network connection to the target address.

If the connection is already established, this method does nothing.

Examples:

Connect to the host.

connection.connect!

Returns:

  • (true)

    If the connection succeeded.

Since:

  • 2.0.0



189
190
191
192
193
194
195
196
197
198
199
# File 'lib/mongo/server/monitor/connection.rb', line 189

def connect!
  if @socket
    raise ArgumentError, 'Monitoring connection already connected'
  end

  @socket = add_server_diagnostics do
    address.socket(socket_timeout, ssl_options.merge(
      connection_address: address, monitor: true))
  end
  true
end

#disconnect!(options = nil) ⇒ true

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.

Note:

This method mutates the connection by setting the socket to nil if the closing succeeded.

Note:

This method accepts an options argument for compatibility with Server::Connections. However, all options are ignored.

Disconnect the connection.

Examples:

Disconnect from the host.

connection.disconnect!

Returns:

  • (true)

    If the disconnect succeeded.

Since:

  • 2.0.0



215
216
217
218
219
220
221
# File 'lib/mongo/server/monitor/connection.rb', line 215

def disconnect!(options = nil)
  if socket
    socket.close rescue nil
    @socket = nil
  end
  true
end

#dispatch(message) ⇒ Protocol::Message

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.

Sends a message and returns the result.

Parameters:

Returns:

Since:

  • 2.0.0



128
129
130
# File 'lib/mongo/server/monitor/connection.rb', line 128

def dispatch(message)
  dispatch_bytes(message.serialize.to_s)
end

#dispatch_bytes(bytes, **opts) ⇒ Protocol::Message

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.

Sends a preserialized message and returns the result.

Parameters:

  • The (String)

    serialized message to send.

  • opts (Hash)

    a customizable set of options

Options Hash (**opts):

  • :read_socket_timeout (Numeric)

    The timeout to use for each read operation.

Returns:

Since:

  • 2.0.0



140
141
142
143
144
145
# File 'lib/mongo/server/monitor/connection.rb', line 140

def dispatch_bytes(bytes, **opts)
  write_bytes(bytes)
  read_response(
    socket_timeout: opts[:read_socket_timeout],
  )
end

#handshake!Object

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



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/mongo/server/monitor/connection.rb', line 223

def handshake!
  payload = if @app_metadata
    @app_metadata.ismaster_bytes
  else
    log_warn("No app metadata provided for handshake with #{address}")
    ISMASTER_BYTES
  end
  message = dispatch_bytes(payload)
  reply = message.documents.first
  set_compressor!(reply)
  @server_connection_id = reply['connectionId']
  reply
rescue => exc
  msg = "Failed to handshake with #{address}"
  Utils.warn_monitor_exception(msg, exc,
    logger: options[:logger],
    log_prefix: options[:log_prefix],
    bg_error_backtrace: options[:bg_error_backtrace],
  )
  raise
end

#read_response(**opts) ⇒ Object

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.

Parameters:

  • opts (Hash)

    a customizable set of options

Options Hash (**opts):

  • :socket_timeout (Numeric)

    The timeout to use for each read operation.

Since:

  • 2.0.0



161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/mongo/server/monitor/connection.rb', line 161

def read_response(**opts)
  unless connected?
    raise ArgumentError, "Trying to read on an unconnected connection #{self}"
  end

  add_server_connection_id do
    add_server_diagnostics do
      Protocol::Message.deserialize(socket,
        Protocol::Message::MAX_MESSAGE_SIZE,
        nil,
        **opts)
    end
  end
end

#socket_timeoutFloat

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.

Returns the monitoring socket timeout.

Note that monitoring connections use the connect timeout value as the socket timeout value. See the Server Discovery and Monitoring specification for details.

Returns:

  • (Float)

    The socket timeout in seconds.

Since:

  • 2.4.3



117
118
119
# File 'lib/mongo/server/monitor/connection.rb', line 117

def socket_timeout
  options[:connect_timeout] || Server::CONNECT_TIMEOUT
end

#write_bytes(bytes) ⇒ Object

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



147
148
149
150
151
152
153
154
155
156
157
# File 'lib/mongo/server/monitor/connection.rb', line 147

def write_bytes(bytes)
  unless connected?
    raise ArgumentError, "Trying to dispatch on an unconnected connection #{self}"
  end

  add_server_connection_id do
    add_server_diagnostics do
      socket.write(bytes)
    end
  end
end