class Mongo::Server::Connection

This class models the socket connections for servers and their behavior.

@since 2.0.0

Constants

PING

The ping command.

@since 2.1.0

@deprecated No longer necessary with Server Selection specification.

PING_BYTES

The ping message as raw bytes.

@since 2.1.0

@deprecated No longer necessary with Server Selection specification.

PING_MESSAGE

Ping message.

@since 2.1.0

@deprecated No longer necessary with Server Selection specification.

PING_OP_MSG

The ping command for an OP_MSG (server versions >= 3.6).

@since 2.5.0

@deprecated No longer necessary with Server Selection specification.

PING_OP_MSG_BYTES

The ping OP_MSG message as raw bytes (server versions >= 3.6).

@since 2.5.0

@deprecated No longer necessary with Server Selection specification.

PING_OP_MSG_MESSAGE

Ping message as an OP_MSG (server versions >= 3.6).

@since 2.5.0

@deprecated No longer necessary with Server Selection specification.

Attributes

last_checkin[R]

The last time the connection was checked back into a pool.

@since 2.5.0

Public Class Methods

new(server, options = {}) click to toggle source

Initialize a new socket connection from the client to the server.

@api private

@example Create the connection.

Connection.new(server)

@note Connection must never be directly instantiated outside of a

Server.

@param [ Mongo::Server ] server The server the connection is for. @param [ Hash ] options The connection options.

@since 2.0.0

# File lib/mongo/server/connection.rb, line 165
def initialize(server, options = {})
  @address = server.address
  @monitoring = server.monitoring
  @options = options.freeze
  @server = server
  @ssl_options = options.reject { |k, v| !k.to_s.start_with?(SSL) }
  @socket = nil
  @last_checkin = nil
  @auth_mechanism = nil
  @pid = Process.pid
end

Public Instance Methods

connect!() click to toggle source

Tell the underlying socket to establish a connection to the host.

@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/connection.rb, line 95
def connect!
  unless socket && socket.connectable?
    @socket = address.socket(socket_timeout, ssl_options)
    address.connect_socket!(socket)
    handshake!
    authenticate!
  end
  true
end
disconnect!() click to toggle source

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.

@return [ true ] If the disconnect succeeded.

@since 2.0.0

# File lib/mongo/server/connection.rb, line 116
def disconnect!
  @auth_mechanism = nil
  @last_checkin = nil
  if socket
    socket.close
    @socket = nil
  end
  true
end
dispatch(messages, operation_id = nil) click to toggle source

Dispatch the provided messages to the connection. If the last message requires a response a reply will be returned.

@example Dispatch the messages.

connection.dispatch([ insert, command ])

@note This method is named dispatch since 'send' is a core Ruby method on

all objects.

@param [ Array<Message> ] messages The messages to dispatch. @param [ Integer ] operation_id The operation id to link messages.

@return [ Protocol::Message ] The reply if needed.

@since 2.0.0

# File lib/mongo/server/connection.rb, line 141
def dispatch(messages, operation_id = nil)
  if monitoring.subscribers?(Monitoring::COMMAND)
    publish_command(messages, operation_id || Monitoring.next_operation_id) do |msgs|
      deliver(msgs)
    end
  else
    deliver(messages)
  end
end
ping() click to toggle source

Ping the connection to see if the server is responding to commands. This is non-blocking on the server side.

@example Ping the connection.

connection.ping

@note This uses a pre-serialized ping message for optimization.

@return [ true, false ] If the server is accepting connections.

@since 2.1.0

@deprecated No longer necessary with Server Selection specification.

# File lib/mongo/server/connection.rb, line 190
def ping
  bytes = features.op_msg_enabled? ? PING_OP_MSG_BYTES : PING_BYTES
  ensure_connected do |socket|
    socket.write(bytes)
    reply = Protocol::Message.deserialize(socket, max_message_size)
    reply.documents[0][Operation::Result::OK] == 1
  end
end
record_checkin!() click to toggle source

Record the last checkin time.

@example Record the checkin time on this connection.

connection.record_checkin!

@return [ self ]

@since 2.5.0

# File lib/mongo/server/connection.rb, line 221
def record_checkin!
  @last_checkin = Time.now
  self
end
socket_timeout() click to toggle source

Get the timeout to execute an operation on a socket.

@example Get the timeout to execute an operation on a socket.

connection.timeout

@return [ Float ] The operation timeout in seconds.

@since 2.0.0

# File lib/mongo/server/connection.rb, line 207
def socket_timeout
  @timeout ||= options[:socket_timeout]
end
Also aliased as: timeout
timeout()

@deprecated Please use :socket_timeout instead. Will be removed in 3.0.0

Alias for: socket_timeout

Private Instance Methods

authenticate!() click to toggle source
# File lib/mongo/server/connection.rb, line 244
def authenticate!
  if options[:user] || options[:auth_mech]
    user = Auth::User.new(Options::Redacted.new(:auth_mech => default_mechanism, :client_key => @client_key).merge(options))
 
    @server.handle_auth_failure! do
      reply = Auth.get(user).login(self)
      @client_key ||= user.send(:client_key) if user.mechanism == :scram
      reply
    end
  end
end
default_mechanism() click to toggle source
# File lib/mongo/server/connection.rb, line 256
def default_mechanism
  @auth_mechanism || (@server.features.scram_sha_1_enabled? ? :scram : :mongodb_cr)
end
deliver(messages) click to toggle source
# File lib/mongo/server/connection.rb, line 228
def deliver(messages)
  write(messages)
  messages.last.replyable? ? read(messages.last.request_id) : nil
end
handshake!() click to toggle source
# File lib/mongo/server/connection.rb, line 233
def handshake!
  if socket && socket.connectable?
    socket.write(app_metadata.ismaster_bytes)
    response = Protocol::Message.deserialize(socket, max_message_size).documents[0]
    min_wire_version = response[Description::MIN_WIRE_VERSION] || Description::LEGACY_WIRE_VERSION
    max_wire_version = response[Description::MAX_WIRE_VERSION] || Description::LEGACY_WIRE_VERSION
    features = Description::Features.new(min_wire_version..max_wire_version)
    @auth_mechanism = (features.scram_sha_1_enabled? || @server.features.scram_sha_1_enabled?) ? :scram : :mongodb_cr
  end
end
write(messages, buffer = BSON::ByteBuffer.new) click to toggle source
# File lib/mongo/server/connection.rb, line 260
def write(messages, buffer = BSON::ByteBuffer.new)
  start_size = 0
  messages.each do |message|
    message.compress!(compressor, options[:zlib_compression_level]).serialize(buffer, max_bson_object_size)
    if max_message_size &&
      (buffer.length - start_size) > max_message_size
      raise Error::MaxMessageSize.new(max_message_size)
      start_size = buffer.length
    end
  end
  ensure_connected{ |socket| socket.write(buffer.to_s) }
end