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

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, #interrupt_socket

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
66
# File 'lib/mongo/server/monitor/connection.rb', line 56

def initialize(address, options = {})
  super()
  @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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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