class Mongo::Server::Monitor::Connection
This class models the monitor connections and their behavior.
@since 2.0.0 @api private
Constants
- ISMASTER
The command used for determining server status.
The case matters here for fail points.
@since 2.2.0
- ISMASTER_BYTES
The raw bytes for the ismaster message.
@since 2.2.0
- ISMASTER_MESSAGE
The constant for the ismaster command.
@since 2.2.0
- ISMASTER_OP_MSG
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_OP_MSG_BYTES
The raw bytes for the ismaster OP_MSG message (server versions >= 3.6).
@since 2.5.0
- ISMASTER_OP_MSG_MESSAGE
The constant for the ismaster command as an OP_MSG (server versions >= 3.6).
@since 2.5.0
Attributes
@return [ Mongo::Address
] address The address to connect to.
@return [ Hash ] options The passed in options.
Public Class Methods
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.
@note Monitoring
connections do not authenticate.
@param [ Mongo::Address
] address The address the connection is for. @param [ Hash ] options The connection options.
@option options [ Mongo::Server::Monitor::AppMetadata
] :app_metadata
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.
@option options [ Array<String> ] :compressors 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'.
@option options [ Float ] :connect_timeout 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
# 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
Public Instance Methods
Establishes a network connection to the target address.
If the connection is already established, this method does nothing.
@example Connect to the host.
connection.connect!
@note This method mutates the connection class by setting a socket if
one previously did not exist.
@return [ true ] If the connection succeeded.
@since 2.0.0
# 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 the connection.
@example Disconnect from the host.
connection.disconnect!
@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.
@return [ true ] If the disconnect succeeded.
@since 2.0.0
# File lib/mongo/server/monitor/connection.rb, line 215 def disconnect!(options = nil) if socket socket.close rescue nil @socket = nil end true end
Sends a message and returns the result.
@param [ Protocol::Message
] message The message to send.
@return [ Protocol::Message
] The result.
# File lib/mongo/server/monitor/connection.rb, line 128 def dispatch(message) dispatch_bytes(message.serialize.to_s) end
Sends a preserialized message and returns the result.
@param [ String ] bytes The serialized message to send.
@option opts [ Numeric ] :read_socket_timeout The timeout to use for
each read operation.
@return [ Protocol::Message
] The result.
# 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
# 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_bg_exception(msg, exc, logger: options[:logger], log_prefix: options[:log_prefix], bg_error_backtrace: options[:bg_error_backtrace], ) raise end
@option opts [ Numeric ] :socket_timeout The timeout to use for
each read operation.
# 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
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.
@return [ Float ] The socket timeout in seconds.
@since 2.4.3
# File lib/mongo/server/monitor/connection.rb, line 117 def socket_timeout options[:connect_timeout] || Server::CONNECT_TIMEOUT end
# 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
Private Instance Methods
# File lib/mongo/server/monitor/connection.rb, line 247 def add_server_connection_id yield rescue Mongo::Error => e if server_connection_id note = "sconn:#{server_connection_id}" e.add_note(note) end raise e end