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

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?, #handshake_command, #handshake_document

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 ‘zstd’, ‘snappy’ and ‘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,

Raises:

  • (ArgumentError)

Since:

  • 2.0.0



56
57
58
59
60
61
62
63
64
65
# File 'lib/mongo/server/monitor/connection.rb', line 56

def initialize(address, options = {})
  @address = address
  @options = options.dup.freeze
  raise ArgumentError, 'App metadata is required' unless @app_metadata = options[:app_metadata]

  @socket = nil
  @pid = Process.pid
  @compressor = nil
  @hello_ok = false
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



71
72
73
# File 'lib/mongo/server/monitor/connection.rb', line 71

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



68
69
70
# File 'lib/mongo/server/monitor/connection.rb', line 68

def options
  @options
end

#server_connection_idInteger (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 server_connection_id The server connection id.

Returns:

  • (Integer)

    server_connection_id The server connection id.

Since:

  • 2.0.0



87
88
89
# File 'lib/mongo/server/monitor/connection.rb', line 87

def server_connection_id
  @server_connection_id
end

Instance Method Details

#check_documentBSON::Document

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.

Build a document that should be used for connection check.

Returns:

  • (BSON::Document)

    Document that should be sent to a server for connection check.

Since:

  • 2.0.0



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

def check_document
  server_api = @app_metadata.server_api || options[:server_api]
  doc = if hello_ok? || server_api
          _doc = HELLO_DOC
          _doc = _doc.merge(Utils.transform_server_api(server_api)) if server_api
          _doc
        else
          LEGACY_HELLO_DOC
        end
  # compressors must be set to maintain correct compression status
  # in the server description. See RUBY-2427
  if compressors = options[:compressors]
    doc = doc.merge(compression: compressors)
  end
  doc
end

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

Raises:

  • (ArgumentError)

Since:

  • 2.0.0



151
152
153
154
155
156
157
158
159
160
# File 'lib/mongo/server/monitor/connection.rb', line 151

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

  @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



176
177
178
179
180
181
182
183
184
185
186
# File 'lib/mongo/server/monitor/connection.rb', line 176

def disconnect!(_options = nil)
  if socket
    begin
      socket.close
    rescue StandardError
      nil
    end
    @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



94
95
96
# File 'lib/mongo/server/monitor/connection.rb', line 94

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:

  • bytes (String)

    The 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



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

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

#handshake!BSON::Document

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.

Send handshake command to connected host and validate the response.

Returns:

  • (BSON::Document)

    Handshake response from server

Raises:

Since:

  • 2.0.0



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/mongo/server/monitor/connection.rb', line 193

def handshake!
  command = handshake_command(
    handshake_document(
      @app_metadata,
      server_api: options[:server_api]
    )
  )
  payload = command.serialize.to_s
  message = dispatch_bytes(payload)
  result = Operation::Result.new(message)
  result.validate!
  reply = result.documents.first
  set_compressor!(reply)
  set_hello_ok!(reply)
  @server_connection_id = reply['connectionId']
  reply
rescue StandardError => e
  msg = "Failed to handshake with #{address}"
  Utils.warn_bg_exception(msg, e,
                          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.

Raises:

  • (ArgumentError)

Since:

  • 2.0.0



125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/mongo/server/monitor/connection.rb', line 125

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

  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



82
83
84
# File 'lib/mongo/server/monitor/connection.rb', line 82

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.

Raises:

  • (ArgumentError)

Since:

  • 2.0.0



113
114
115
116
117
118
119
120
121
# File 'lib/mongo/server/monitor/connection.rb', line 113

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

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