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,

Since:

  • 2.0.0



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

def initialize(address, options = {})
  @address = address
  @options = options.dup.freeze
  unless @app_metadata = options[:app_metadata]
    raise ArgumentError, 'App metadata is required'
  end
  @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



74
75
76
# File 'lib/mongo/server/monitor/connection.rb', line 74

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



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

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



90
91
92
# File 'lib/mongo/server/monitor/connection.rb', line 90

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



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/mongo/server/monitor/connection.rb', line 229

def check_document
  server_api = @app_metadata.server_api || options[:server_api]
  doc = if hello_ok? || server_api
    _doc = HELLO_DOC
    if server_api
      _doc = _doc.merge(Utils.transform_server_api(server_api))
    end
    _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.

Since:

  • 2.0.0



158
159
160
161
162
163
164
165
166
167
168
# File 'lib/mongo/server/monitor/connection.rb', line 158

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



184
185
186
187
188
189
190
# File 'lib/mongo/server/monitor/connection.rb', line 184

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



97
98
99
# File 'lib/mongo/server/monitor/connection.rb', line 97

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



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

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



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

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 => exc
  msg = "Failed to handshake with #{address}"
  Utils.warn_bg_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



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/mongo/server/monitor/connection.rb', line 130

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



85
86
87
# File 'lib/mongo/server/monitor/connection.rb', line 85

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



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/mongo/server/monitor/connection.rb', line 116

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