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

PING_BYTES

The ping message as raw bytes.

@since 2.1.0

PING_MESSAGE

Ping message.

@since 2.1.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 129
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
  @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 60
def connect!
  unless socket && socket.connectable?
    @socket = address.socket(timeout, ssl_options)
    socket.connect!
    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 81
def disconnect!
  if socket
    socket.close
    @auth_mechanism = nil
    @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::Reply ] The reply if needed.

@since 2.0.0

# File lib/mongo/server/connection.rb, line 105
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

# File lib/mongo/server/connection.rb, line 151
def ping
  ensure_connected do |socket|
    socket.write(PING_BYTES)
    reply = Protocol::Reply.deserialize(socket, max_message_size)
    reply.documents[0][Operation::Result::OK] == 1
  end
end

Private Instance Methods

authenticate!() click to toggle source
# File lib/mongo/server/connection.rb, line 177
def authenticate!
  if options[:user] || options[:auth_mech]
    user = Auth::User.new(Options::Redacted.new(:auth_mech => default_mechanism).merge(options))
    @server.handle_auth_failure! do
      Auth.get(user).login(self)
    end
  end
end
default_mechanism() click to toggle source
# File lib/mongo/server/connection.rb, line 186
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 161
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 166
def handshake!
  if socket && socket.connectable?
    socket.write(app_metadata.ismaster_bytes)
    response = Protocol::Reply.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 190
def write(messages, buffer = BSON::ByteBuffer.new)
  start_size = 0
  messages.each do |message|
    message.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